Supplementary methods
\(~\)
LHM culturing
We maintained this LHM stock in our laboratory for 32
generations prior to creating the genotypes required for experimental
evolution. We cultured LHM at 25C, with a 16-8 light-dark
cycle and reared in vials (95mm x 25mm) on a corn-meal, yeast and
dextrose-based diet (recipe in Table S1; ~8cm3 of food medium per vial)
supplemented with dried yeast, at a population size of at least 800
breeding individuals across 25 vials (16 flies of each sex per vial,
following Rice et al. 2005). Each generation begins by pooling
the offspring produced across the 25 vials and randomly assorting 16
female-male pairs to 25 new vials. We then allow these breeding
individuals 48 hours to interact and mate, before transferring them to
another set of new vials. After 24 hours of egg-laying, we discard all
adults, and allow juveniles 12 days to compete for resources, pupate and
eclose as adults. We then iteratively repeat this process each
generation to maintain the population.
\(~\)
Creating the genotypes used for experimental
evolution
img <- readPNG("Figure_S1.png")
grid.raster(img)

Figure S1. Crossing scheme used to integrate the GFP
constructs and apXA marked translocated second and
third chromosome balancers into the LHM genetic background.
We replicated the crosses 12 times to supply the flies used in
generation zero of experimental evolution; 6 times using the
Ubi GFP construct and 6 times with the 3xP construct.
G = generation.
\(~\)
Table S1. Recipe for food medium used in our
experiment. The provided quantities make ~ 1 litre of food.
tibble("Ingredients" = c("Soy flour", "Cornmeal", "Yeast", "Dextrose", "Agar", "Water", "Tegosept", "Acid mix (4 mL orthophosphoric acid, 41 mL propionic acid, 55 mL water to make 100 mL)"),
"Quantity" = c("20 g", "73 g", "35 g", "75 g", "6 g", "1000 mL", "17 mL", "14 mL")) %>%
pander(split.cell = 40, split.table = Inf)
| Soy flour |
20 g |
| Cornmeal |
73 g |
| Yeast |
35 g |
| Dextrose |
75 g |
| Agar |
6 g |
| Water |
1000 mL |
| Tegosept |
17 mL |
| Acid mix (4 mL orthophosphoric acid, 41 mL propionic
acid, 55 mL water to make 100 mL) |
14 mL |
\(~\)
Analysis
Load in the data
\(~\)
fitness_data <- read_csv("data/SLC_fitness_data.csv") %>%
mutate(Fitness_vial_ID = as.factor(Fitness_vial_ID),
Block = as.factor(Block),
Population = as.factor(Population),
Treatment = as.factor(Treatment),
GFP = as.factor(GFP),
Sex = as.factor(Sex),
Rearing_vial = as.factor(Rearing_vial),
Total_red_offspring = Red_female_offspring + Red_male_offspring,
Total_bw_offspring = bw_female_offspring + bw_male_offspring,
Total_offspring = Total_red_offspring + Total_bw_offspring) %>%
rename(Inheritance_treatment = Treatment)
# Create a function to build HTML searchable tables
my_data_table <- function(df){
datatable(
df, rownames=FALSE,
autoHideNavigation = TRUE,
extensions = c("Scroller", "Buttons"),
options = list(
dom = 'Bfrtip',
deferRender=TRUE,
scrollX=TRUE, scrollY=400,
scrollCollapse=TRUE,
buttons =
list('pageLength', 'colvis', 'csv', list(
extend = 'pdf',
pageSize = 'A4',
orientation = 'landscape',
filename = 'fitness_data')),
pageLength = 692
)
)
}
my_data_table(fitness_data %>% select(-Comment))
Column explanations
Fitness_vial_ID: a unique identifier for each trial of the fitness
assay.
Block: the experiment was run in three distinct blocks, using flies
from separate generations.
Population: we measured the fitness of flies from 12 independent
populations that contained autosomes that had undergone experimental
evolution.
Inheritance_treatment: the populations carried autosomes that had
been exposed to one of three inheritance treatments for 20 generations:
a female-limited inheritance treatment where autosomes were always
passed from mother to daughter, a male-limited treatment where autosomes
were passed from father to son, and a control condition where
inheritance was unconstrained.
GFP: the GFP marker carried by the population. UBI indicates the
presence of a transgene that encodes ubiquitous expression of GFP, while
3xP indicates the presence of a different transgene that encodes the
expression of GFP in the ocelli.
Sex: the sex of the individuals that we were measuring the fitness
of.
Rearing_vial: the vial the treatment flies used in the trial
developed in. This variable is included to capture variation explained
by the rearing environment e.g. small differences in food moisture
content or quantity. Note that females and males can have the same
rearing vial as the sexes were reared together.
Red_female_offspring: the number of adult female offspring
sired/produced by flies sourced from one of the 12 populations.
Red_male_offspring: the number of adult male offspring sired/produced
by flies sourced from one of the 12 populations.
bw_female_offspring: the number of adult female offspring
sired/produced by the competitor flies in our fitness assay. bw
is a recessive allele that encodes brown eye colour.
bw_male_offspring: the number of adult male offspring sired/produced
by the competitor flies in our fitness assay. bw is a recessive
allele that encodes brown eye colour.
Total_red_offspring: the total number (sexes pooled) of adult
offspring sired/produced by flies sourced from one of the 12
populations.
Total_bw_offspring: the total number (sexes pooled) of adult
offspring sired/produced by competitor flies.
Total_offspring: the total number (sexes and eye colours pooled) of
adult offspring counted in each vial.
\(~\)
Modelling approach
\(~\)
Female and male fitness are fundamentally different concepts /
traits. There are also several differences between our female and male
fitness assays. The major difference is that the male assay contains
half the number of females in any given vial than does the female assay.
The logic behind this design choice is that sexually selected processes
are a more important determinant of male fitness than they are female
fitness, so any fitness differences may only be observed when
competition for fertilisations is high.
For these reasons, we choose to split the data up and model female
and male fitness separately.
female_fitness <-
fitness_data %>%
filter(Sex == "Female")
male_fitness <-
fitness_data %>%
filter(Sex == "Male") %>%
mutate(prop_red = Total_red_offspring / Total_offspring)
We fit the following fixed and random effects to model female and
male fitness. Our aim is to estimate the causal effect that
Inheritance_treatment (I) has on
fitness (F).
Fixed effects
Inheritance_treatment (I): this is the inheritance
regime that the autosomes carried by each of the populations were
subject to for 20 generations. There are three levels: populations
carrying female-adapted autosomes, populations containing male-adapted
autosomes and populations carrying control autosomes that experienced an
unmanipulated inheritance regime. We are designing our model to test for
a causal effect of this variable.
Mediator variables
Block (B): fitness might differ between the three
distinct blocks we split our experiment up into. Blocks differed
temporally, used flies from different generations and different batches
of food. It is also possible that there were minor fluctuations in the
lighting and temperature environment experienced during development
between blocks. Each of these variables may introduce variation into our
fitness measurements, that can be accounted for by including the
Block variable in our model.
GFP (G): it is possible that fitness may be affected by
the GFP transgene carried by each population. For example, one could
imagine that any unintended fitness effects of a transgene might be of
greater magnitude if it is expressed in a larger proportion of tissues,
as is the case for the UBI transgene versus the 3xP
transgene. Note that each GFP type is carried by an equal number of
populations from each of the three evolutionary treatments.
Varying/Random effects
Population (P): our design contained 12 independent
populations of autosomes that originated from a single outbred
laboratory fly population. The populations were split and autosomes from
each were subjected to one of the three evolution treatments for 20
generations. 4 populations experienced a female-limited inheritance
regime, 4 a male-limited regime and 4 an unlimited or control
regime.
Rearing_vial (R): the vial individual flies developed
within may introduce further variation into our response variable. Like
Block this variable controls for micro-environmental
variation.
\(~\)
Accounting for over-dispersion
The data is over-dispersed with several highly influential (outlier)
observations that have large effects on our posterior prediction. To
combat this, we fit models following the betabinomial
distribution family, as this is better equipped to deal with extreme
values at the tails i.e. overdispersion.
However, the beta-binomial is not a native family in
brms, we need to create the distribution family using the
custom_family() function. The code below is taken directly
from the brms_customfamilies vignette, which can be viewed
here.
beta_binomial2 <- custom_family(
"beta_binomial2", dpars = c("mu", "phi"),
links = c("logit", "log"), lb = c(NA, 2),
# note that we set the lower bound to 2, following McElreath, rather than Buerkner. This means that the most conservative estimate for phi we get is a flat expectation between 0 and 1
type = "int", vars = "vint1[n]"
)
stan_funs <- "
real beta_binomial2_lpmf(int y, real mu, real phi, int T) {
return beta_binomial_lpmf(y | T, mu * phi, (1 - mu) * phi);
}
int beta_binomial2_rng(real mu, real phi, int T) {
return beta_binomial_rng(T, mu * phi, (1 - mu) * phi);
}
"
stanvars <- stanvar(scode = stan_funs, block = "functions")
\(~\)
Female fitness
\(~\)
To estimate the fitness of females carrying each of the three
autosome types, we placed three experimental females into a yeasted vial
with three female competitors that carried the bw mutation. We
then introduced six males that also carried the bw mutation. We
allowed them to mate and oviposit for three days, then removed all
adults from the vial. 12 days later we counted all of the adult progeny
in the vial and scored them for eye-colour. Progeny with red eyes were
produced by the experimental females ( bw is recessive) and
progeny with brown eyes were produced by the competitor females. We
calculated fitness as the proportion of red eyed offspring in the
vial.
We present the fixed effects from the model:
\(~\)
female_fitness_model <-
brm(Total_red_offspring | vint(Total_offspring) ~ 1 + Inheritance_treatment + Block + GFP + (1|Population) + (1|Rearing_vial),
data = female_fitness, family = beta_binomial2,
prior = c(prior(normal(0, 1), class = Intercept), # this sets the prior mean at 0.5 relative fitness
prior(normal(0, 1.5), class = b),
prior(exponential(1), class = phi)),
iter = 8000, warmup = 4000, chains = 4, cores = 4,
control = list(adapt_delta = 0.98, max_treedepth = 10),
seed = 2, stanvars = stanvars, file = "Fits/female_fitness.model")
fixef(female_fitness_model) %>%
kable(digits = 3) %>%
kable_styling()
|
|
Estimate
|
Est.Error
|
Q2.5
|
Q97.5
|
|
Intercept
|
1.110
|
0.095
|
0.921
|
1.296
|
|
Inheritance_treatmentFemale_limited
|
0.174
|
0.104
|
-0.031
|
0.383
|
|
Inheritance_treatmentMale_limited
|
0.187
|
0.104
|
-0.014
|
0.398
|
|
Block2
|
-0.637
|
0.079
|
-0.792
|
-0.480
|
|
Block3
|
-0.624
|
0.071
|
-0.765
|
-0.487
|
|
GFPUBI
|
-0.323
|
0.084
|
-0.488
|
-0.156
|
We need to write some additional code to get some post processing
stuff i.e. LOO to work. Code courtesy of the
brms_customfamilies vignette, which can be viewed here.
Run LOO to see if we’ve effectively modelled over dispersion.
female_fitness_model <- add_criterion(female_fitness_model, criterion = "loo", file = "Fits/female_fitness.model")
loo(female_fitness_model)
##
## Computed from 16000 by 327 log-likelihood matrix
##
## Estimate SE
## elpd_loo -1400.2 10.7
## p_loo 23.1 2.1
## looic 2800.4 21.3
## ------
## Monte Carlo SE of elpd_loo is 0.1.
##
## All Pareto k estimates are good (k < 0.5).
## See help('pareto-k-diagnostic') for details.
The beta-binomial model looks good. It returns no points with high
pareto k values.
Conduct a posterior predictive check to confirm our model is doing
what we want it to.
pp_check(female_fitness_model, type = "hist", ndraws = 11, binwidth = 10) +
theme_minimal() +
theme(panel.background = element_blank())

The posterior predictive distribution recapitulates our raw data
quite well, indicating the model is making sensible predictions.
\(~\)
Derive predictions from the posterior
Get predictions from the model
Table S2. Estimated female fitness for flies
carrying autosomes derived from each of the three inheritance
regimes.
draws <- as_draws_df(female_fitness_model)
draws_female <-
draws %>%
mutate(`Female-limited` = inv_logit_scaled(b_Intercept + b_Inheritance_treatmentFemale_limited),
`Male-limited` = inv_logit_scaled(b_Intercept + b_Inheritance_treatmentMale_limited),
Control = inv_logit_scaled(b_Intercept)) %>%
select(`Female-limited`, Control, `Male-limited`) %>%
pivot_longer(cols = c(`Female-limited`, Control, `Male-limited`),
names_to = "Inheritance treatment") %>%
rename(prop_focal_offspring = value) %>%
arrange(`Inheritance treatment`)
draws_female %>%
group_by(`Inheritance treatment`) %>%
summarise(`Estimated prop. of offspring produced` = mean(prop_focal_offspring),
`2.5%` = quantile(prop_focal_offspring, probs = 0.025),
`97.5%` = quantile(prop_focal_offspring, probs = 0.975)) %>%
pander(split.cell = 40, split.table = Inf, round = 3)
| Control |
0.752 |
0.715 |
0.785 |
| Female-limited |
0.783 |
0.749 |
0.814 |
| Male-limited |
0.785 |
0.752 |
0.815 |
Table S3. Differences in female fitness between each
of the three inheritance regimes.
# Find differences and visualise in table
draws_diff <- draws %>%
mutate(`Female-limited` = inv_logit_scaled(b_Intercept + b_Inheritance_treatmentFemale_limited),
`Male-limited` = inv_logit_scaled(b_Intercept + b_Inheritance_treatmentMale_limited),
Control = inv_logit_scaled(b_Intercept)) %>%
mutate(`Female - Control` = `Female-limited` - Control,
`Male - Control` = `Male-limited` - Control,
`Female - Male` = `Female-limited` - `Male-limited`) %>%
select(`Female - Control`, `Male - Control`, `Female - Male`)
rbind(
draws_diff %>%
summarise(`Diff in offspring produced per 100` = mean(`Male - Control`)*100,
`2.5%` = quantile(`Male - Control`, probs = 0.025) *100,
`97.5%` = quantile(`Male - Control`, probs = 0.975) *100) %>%
mutate(Contrast = "Male inherited - Control"),
draws_diff %>%
summarise(`Diff in offspring produced per 100` = mean(`Female - Control`)*100,
`2.5%` = quantile(`Female - Control`, probs = 0.025) *100,
`97.5%` = quantile(`Female - Control`, probs = 0.975) *100) %>%
mutate(Contrast = "Female inherited - Control"),
draws_diff %>%
summarise(`Diff in offspring produced per 100` = mean(`Female - Male`)*100,
`2.5%` = quantile(`Female - Male`, probs = 0.025) *100,
`97.5%` = quantile(`Female - Male`, probs = 0.975) *100) %>%
mutate(Contrast = "Female inherited - Male inherited")
) %>%
select(Contrast, `Diff in offspring produced per 100`, `2.5%`, `97.5%`) %>%
pander(split.cell = 40, split.table = Inf, round = 2)
| Male inherited - Control |
3.32 |
-0.25 |
7.11 |
| Female inherited - Control |
3.09 |
-0.56 |
6.84 |
| Female inherited - Male inherited |
-0.23 |
-3.7 |
3.2 |
The effects of the block and GFP predictors
Table S4. The effects of the fixed predictor
variables on female fitness that are not directly related to intralocus
sexual conflict. Female fitness measured in Block 1 was higher than that
measured in Blocks 2 and 3. Females carrying autosomes marked with 3xP
GFP had higher fitness than those expressing UBI GFP.
draws_diff_other <- draws %>%
select(b_Intercept, b_Block2, b_Block3, b_GFPUBI) %>%
mutate(`Block 1, 3xP` = inv_logit_scaled(b_Intercept),
`Block 2` = inv_logit_scaled(b_Intercept + b_Block2),
`Block 3` = inv_logit_scaled(b_Intercept + b_Block3),
UBI = inv_logit_scaled(b_Intercept + b_GFPUBI)) %>%
mutate(`Block 1 - Block 2` = `Block 1, 3xP` - `Block 2`,
`Block 1 - Block 3` = `Block 1, 3xP` - `Block 3`,
`3xP - UBI` = `Block 1, 3xP` - UBI) %>%
select(`Block 1 - Block 2`, `Block 1 - Block 3`, `3xP - UBI`)
# Find differences and visualise in table
rbind(
draws_diff_other %>%
summarise(`Diff in offspring produced per 100` = mean(`Block 1 - Block 2`)*100,
`2.5%` = quantile(`Block 1 - Block 2`, probs = 0.025) *100,
`97.5%` = quantile(`Block 1 - Block 2`, probs = 0.975) *100) %>%
mutate(Contrast = "Block 1 - Block 2"),
draws_diff_other %>%
summarise(`Diff in offspring produced per 100` = mean(`Block 1 - Block 3`)*100,
`2.5%` = quantile(`Block 1 - Block 3`, probs = 0.025) *100,
`97.5%` = quantile(`Block 1 - Block 3`, probs = 0.975) *100) %>%
mutate(Contrast = "Block 1 - Block 3"),
draws_diff_other %>%
summarise(`Diff in offspring produced per 100` = mean(`3xP - UBI`)*100,
`2.5%` = quantile(`3xP - UBI`, probs = 0.025) *100,
`97.5%` = quantile(`3xP - UBI`, probs = 0.975) *100) %>%
mutate(Contrast = "3xP - UBI")
) %>%
select(Contrast, `Diff in offspring produced per 100`, `2.5%`, `97.5%`) %>%
pander(split.cell = 40, split.table = Inf, round = 2)
| Block 1 - Block 2 |
13.59 |
10.1 |
17.08 |
| Block 1 - Block 3 |
13.27 |
10.35 |
16.32 |
| 3xP - UBI |
6.48 |
3.11 |
9.84 |
\(~\)
Male fitness
\(~\)
To estimate the fitness of males carrying each of the three
chromosome types, we conducted an experiment very similar to the female
fitness assay. However, because male fitness has stronger covariance
with fertilisation events than does female fitness, we conducted the
male fitness assay with a 1:2 sex ratio (female:male) rather than the
1:1 ratio used in the female assay. This increases the strength of
sexual selection and is a more appropriate way to expose differences in
fitness between groups of males. As with the females, we calculated
fitness as the proportion of red-eyed offspring in the vial.
male_fitness_model <-
brm(Total_red_offspring | vint(Total_offspring) ~ 1 + Inheritance_treatment + Block + GFP + (1|Population) + (1|Rearing_vial),
data = male_fitness, family = beta_binomial2,
prior = c(prior(normal(0, 1), class = Intercept),
prior(normal(0, 1.5), class = b),
prior(exponential(1), class = phi)),
iter = 8000, warmup = 4000, chains = 4, cores = 4,
control = list(adapt_delta = 0.95, max_treedepth = 10),
seed = 2, stanvars = stanvars, file = "Fits/male_fitness.model")
fixef(male_fitness_model) %>%
kable(digits = 3) %>%
kable_styling()
|
|
Estimate
|
Est.Error
|
Q2.5
|
Q97.5
|
|
Intercept
|
0.761
|
0.233
|
0.291
|
1.217
|
|
Inheritance_treatmentFemale_limited
|
0.422
|
0.270
|
-0.126
|
0.970
|
|
Inheritance_treatmentMale_limited
|
0.107
|
0.265
|
-0.428
|
0.632
|
|
Block2
|
0.970
|
0.148
|
0.682
|
1.261
|
|
Block3
|
-0.035
|
0.141
|
-0.311
|
0.240
|
|
GFPUBI
|
-0.336
|
0.218
|
-0.771
|
0.103
|
Run LOO to see if we’ve effectively modelled over dispersion.
male_fitness_model <- add_criterion(male_fitness_model, criterion = "loo", file = "Fits/male_fitness.model")
loo(male_fitness_model)
##
## Computed from 16000 by 360 log-likelihood matrix
##
## Estimate SE
## elpd_loo -1561.9 21.4
## p_loo 23.1 1.9
## looic 3123.8 42.8
## ------
## Monte Carlo SE of elpd_loo is NA.
##
## Pareto k diagnostic values:
## Count Pct. Min. n_eff
## (-Inf, 0.5] (good) 357 99.2% 5284
## (0.5, 0.7] (ok) 2 0.6% 5066
## (0.7, 1] (bad) 0 0.0% <NA>
## (1, Inf) (very bad) 1 0.3% 8000
## See help('pareto-k-diagnostic') for details.
There is one point having a large effect on the posterior. Upon
inspection, this data point is not an unreasonable one and there is no
cause to remove it from the dataset. It also does not change the causal
effect of inheritance treatment on male fitness.
Conduct the posterior predictive check…
pp_check(male_fitness_model, type = "hist", ndraws = 11, binwidth = 10) +
theme_minimal() +
theme(panel.background = element_blank())

Derive estimates from posterior
Get predictions from the model
Table S5. Estimated male fitness for flies carrying
autosomes derived from each of the three inheritance regimes.
draws_m <- as_draws_df(male_fitness_model)
# predictions averaged over mediator variables
draws_male <-
draws_m %>%
mutate(`Female-limited` = inv_logit_scaled(b_Intercept + b_Inheritance_treatmentFemale_limited),
`Male-limited` = inv_logit_scaled(b_Intercept + b_Inheritance_treatmentMale_limited),
Control = inv_logit_scaled(b_Intercept)) %>%
select(Control, `Female-limited`, `Male-limited`) %>%
pivot_longer(cols = c(Control, `Female-limited`, `Male-limited`),
names_to = "Inheritance treatment") %>%
rename(prop_focal_offspring = value)
draws_male %>%
group_by(`Inheritance treatment`) %>%
summarise(`Estimated prop. of offspring sired` = mean(prop_focal_offspring),
`2.5%` = quantile(prop_focal_offspring, probs = 0.025),
`97.5%` = quantile(prop_focal_offspring, probs = 0.975)) %>%
pander(split.cell = 40, split.table = Inf, round = 3)
| Control |
0.679 |
0.572 |
0.771 |
| Female-limited |
0.763 |
0.67 |
0.84 |
| Male-limited |
0.702 |
0.598 |
0.792 |
Table S6. Differences in male fitness between each
of the three inheritance regimes.
draws_diff_m <- draws_m %>%
mutate(`Female-limited` = inv_logit_scaled(b_Intercept + b_Inheritance_treatmentFemale_limited),
`Male-limited` = inv_logit_scaled(b_Intercept + b_Inheritance_treatmentMale_limited),
Control = inv_logit_scaled(b_Intercept)) %>%
mutate(`Female - Control` = `Female-limited` - Control,
`Male - Control` = `Male-limited` - Control,
`Female - Male` = `Female-limited` - `Male-limited`) %>%
select(`Female - Control`, `Male - Control`, `Female - Male`)
# Find differences and visualise in table
rbind(
draws_diff_m %>%
summarise(`Diff in offspring produced per 100` = mean(`Female - Control`)*100,
`2.5%` = quantile(`Female - Control`, probs = 0.025) *100,
`97.5%` = quantile(`Female - Control`, probs = 0.975) *100) %>%
mutate(Contrast = "Female inherited - Control"),
draws_diff_m %>%
summarise(`Diff in offspring produced per 100` = mean(`Male - Control`)*100,
`2.5%` = quantile(`Male - Control`, probs = 0.025) *100,
`97.5%` = quantile(`Male - Control`, probs = 0.975) *100) %>%
mutate(Contrast = "Male inherited - Control"),
draws_diff_m %>%
summarise(`Diff in offspring produced per 100` = mean(`Female - Male`)*100,
`2.5%` = quantile(`Female - Male`, probs = 0.025) *100,
`97.5%` = quantile(`Female - Male`, probs = 0.975) *100) %>%
mutate(Contrast = "Female inherited - Male inherited")
) %>%
select(Contrast, `Diff in offspring produced per 100`, `2.5%`, `97.5%`) %>%
pander(split.cell = 40, split.table = Inf, round = 2)
| Female inherited - Control |
8.33 |
-2.44 |
19.22 |
| Male inherited - Control |
2.26 |
-9.22 |
13.44 |
| Female inherited - Male inherited |
6.08 |
-4.42 |
16.8 |
The effects of the block and GFP predictors
Table S7. The effects of the fixed predictor
variables on male fitness that are not directly related to intralocus
sexual conflict. Male fitness measured in Block 2 was higher than that
measured in Blocks 1 and 3. There was no effect of GFP transgene on male
fitness.
draws_diff_other_m <- draws_m %>%
select(b_Intercept, b_Block2, b_Block3, b_GFPUBI) %>%
mutate(`Block 1, 3xP` = inv_logit_scaled(b_Intercept),
`Block 2` = inv_logit_scaled(b_Intercept + b_Block2),
`Block 3` = inv_logit_scaled(b_Intercept + b_Block3),
UBI = inv_logit_scaled(b_Intercept + b_GFPUBI)) %>%
mutate(`Block 1 - Block 2` = `Block 1, 3xP` - `Block 2`,
`Block 1 - Block 3` = `Block 1, 3xP` - `Block 3`,
`3xP - UBI` = `Block 1, 3xP` - UBI) %>%
select(`Block 1 - Block 2`, `Block 1 - Block 3`, `3xP - UBI`)
# Find differences and visualise in table
rbind(
draws_diff_other_m %>%
summarise(`Diff in offspring produced per 100` = mean(`Block 1 - Block 2`)*100,
`2.5%` = quantile(`Block 1 - Block 2`, probs = 0.025) *100,
`97.5%` = quantile(`Block 1 - Block 2`, probs = 0.975) *100) %>%
mutate(Contrast = "Block 1 - Block 2"),
draws_diff_other_m %>%
summarise(`Diff in offspring produced per 100` = mean(`Block 1 - Block 3`)*100,
`2.5%` = quantile(`Block 1 - Block 3`, probs = 0.025) *100,
`97.5%` = quantile(`Block 1 - Block 3`, probs = 0.975) *100) %>%
mutate(Contrast = "Block 1 - Block 3"),
draws_diff_other_m %>%
summarise(`Diff in offspring produced per 100` = mean(`3xP - UBI`)*100,
`2.5%` = quantile(`3xP - UBI`, probs = 0.025) *100,
`97.5%` = quantile(`3xP - UBI`, probs = 0.975) *100) %>%
mutate(Contrast = "3xP - UBI")
) %>%
select(Contrast, `Diff in offspring produced per 100`, `2.5%`, `97.5%`) %>%
pander(split.cell = 40, split.table = Inf, round = 2)
| Block 1 - Block 2 |
-16.76 |
-23.17 |
-10.91 |
| Block 1 - Block 3 |
0.75 |
-5.25 |
6.8 |
| 3xP - UBI |
7.62 |
-2.31 |
17.49 |
\(~\)
Building Figure 2
# female plots
f_1 <-
draws_female %>%
mutate(`Inheritance treatment` = fct_relevel(`Inheritance treatment`, "Female-limited", "Control", "Male-limited")) %>%
ggplot(aes(`Inheritance treatment`, prop_focal_offspring)) +
stat_halfeye(fill = "grey", .width = c(0.66, 0.95), alpha = 1,
point_interval = "mean_qi", point_fill = "white",
shape = 21, point_size = 3, stroke = 1.5) + # width indicates the uncertainty intervals: we have 66% and 95% intervals
#scale_fill_manual(values = met.brewer("Hiroshige", 3)) +
coord_flip() +
ylab("Female fitness\n(prop. offspring produced)") +
theme_bw() +
theme(legend.position = "none",
panel.grid.minor = element_blank())
f_2 <-
draws_diff %>%
gather(key = parameter, value = `Fitness difference`) %>%
as_tibble() %>%
ggplot(aes(parameter, `Fitness difference`)) +
stat_halfeye(.width = c(0.66, 0.95), alpha = 0.9, point_interval = "mean_qi",
slab_fill = "grey",
shape = 21, point_size = 3, stroke = 1.5,
point_fill = "white") + # width indicates the uncertainty intervals: here we have 66% and 95% intervals
coord_flip() +
geom_hline(yintercept = 0, linetype = 2) +
#scale_y_continuous(breaks = c(, 0, 1)) +
xlab("Treatment contrast") +
ylab("Female fitness difference\n(prop. offspring produced)") +
theme_bw() +
theme(legend.position = "none",
panel.grid.minor = element_blank())
# male plots
f_3 <-
draws_male %>%
mutate(`Inheritance treatment` = fct_relevel(`Inheritance treatment`, "Female-limited", "Control", "Male-limited")) %>%
ggplot(aes(`Inheritance treatment`, prop_focal_offspring)) +
stat_halfeye(fill = "grey", .width = c(0.66, 0.95), alpha = 1,
point_interval = "mean_qi", point_fill = "white",
shape = 21, point_size = 3, stroke = 1.5) + # width indicates the uncertainty intervals: here we have 66% and 95% intervals
scale_fill_manual(values = met.brewer("Hiroshige", 3)) +
coord_flip() +
ylab("Male fitness\n(prop. offspring produced)") +
theme_bw() +
theme(legend.position = "none",
panel.grid.minor = element_blank())
f_4 <-
draws_diff_m %>%
gather(key = parameter, value = `Fitness difference`) %>%
as_tibble() %>%
ggplot(aes(parameter, `Fitness difference`)) +
stat_halfeye(.width = c(0.66, 0.95), alpha = 0.9, point_interval = "mean_qi",
slab_fill = "grey",
shape = 21, point_size = 3, stroke = 1.5,
point_fill = "white") + # width indicates the uncertainty intervals: here we have 66% and 95% intervals
scale_fill_manual(values = met.brewer("Hokusai3", 3)) +
coord_flip() +
geom_hline(yintercept = 0, linetype = 2) +
scale_y_continuous(breaks = c(-0.2, -0.1, 0, 0.1, 0.2)) +
xlab("Treatment contrast") +
ylab("Male fitness difference\n(prop. offspring sired)") +
theme_bw() +
theme(legend.position = "none",
panel.grid.minor = element_blank())
(f_1 + f_2) /(f_3 + f_4) +
plot_annotation(tag_levels = 'a')

Figure 2: a shows the estimated
distribution of the mean for female fitness for flies carrying autosomes
that had previously experienced unconstrained inheritance (control),
female-limited inheritance or male-limited inheritance.
b shows the difference contrast in female fitness
between each of the three inheritance treatments. This difference is on
the proportion scale, where a value of 0.1 indicates that females of a
given inheritance treatment produce 10 more offspring per every 100 when
cohabiting with bw competitor females. c and
d depict the same things as a and
b, except for male fitness.
LS0tCnRpdGxlOiAiRXhwZXJpbWVudGFsIGVuZm9yY2VtZW50IG9mIHNleC1saW1pdGVkIGF1dG9zb21lIGluaGVyaXRhbmNlIGRvZXMgbm90IHJldmVhbCBpbnRyYWxvY3VzIHNleHVhbCBjb25mbGljdCIKYXV0aG9yOiAiVGhvbWFzIEtlYW5leSwgSGVpZGkgV29uZywgVGhlcmVzYSBKb25lcyBhbmQgTHVrZSBIb2xtYW4iCiNiaWJsaW9ncmFwaHk6ICJzdXBwX3JlZmVyZW5jZXMuYmliIgpvdXRwdXQ6CiAgaHRtbF9kb2N1bWVudDoKICAgIGNvZGVfZm9sZGluZzogaGlkZQogICAgZGVwdGg6IDEKICAgIG51bWJlcl9zZWN0aW9uczogbm8KICAgIHRoZW1lOiB5ZXRpCiAgICB0b2M6IHllcwogICAgdG9jX2Zsb2F0OiB5ZXMKICAgIGNvZGVfZG93bmxvYWQ6IHRydWUKZWRpdG9yX29wdGlvbnM6CiAgY2h1bmtfb3V0cHV0X3R5cGU6IGNvbnNvbGUKLS0tCgoKCmBgYHtyfQprbml0cjo6b3B0c19jaHVuayRzZXQoZWNobyA9IFRSVUUsIHdhcm5pbmcgPSBGQUxTRSwgbWVzc2FnZSA9IEZBTFNFLCBjYWNoZSA9IEZBTFNFKQpgYGAKCiMgTG9hZCBwYWNrYWdlcwoKYGBge3J9CmxpYnJhcnkoTWF0cml4KSAjIG15IHBjIG5lZWRzIHRoaXMgdG8gbG9hZCB0aGUgdGlkeXZlcnNlIGNvcnJlY3RseQpsaWJyYXJ5KHRpZHl2ZXJzZSkgIyB0aWR5IHN0eWxlIGNvZGluZwpsaWJyYXJ5KHBuZykgIyB0byBsb2FkIGltYWdlcwpsaWJyYXJ5KGdyaWQpICMgdG8gcGxvdCBpbWFnZXMKbGlicmFyeShicm1zKSAjIEJheWVzaWFuIG1vZGVscwpsaWJyYXJ5KGxvbykgIyB0byB1c2UgaW5mb3JtYXRpb24gY3JpdGVyaWEgaW4gYnJtcyBtb2RlbHMKbGlicmFyeShkYWdpdHR5KSAjIHRvIGJ1aWxkIERBR3MKbGlicmFyeShnZ2RhZykgIyB0byB0aWR5IERBR3MKbGlicmFyeSh0aWR5YmF5ZXMpICMgQmF5ZXNpYW4gYWVzdGhldGljcwpsaWJyYXJ5KE1ldEJyZXdlcikgIyBjb2xvdXJzCmxpYnJhcnkoa2FibGVFeHRyYSkgIyB0YWJsZXMKbGlicmFyeShwYXRjaHdvcmspICMgcHV0dGluZyBwbG90cyB0b2dldGhlcgpsaWJyYXJ5KERUKSAjIGZvciBzZWFyY2gtIGFuZCBzYXZlYWJsZSB0YWJsZXMKbGlicmFyeShwYW5kZXIpICMgZm9yIHNpbXBsZXIgdGFibGVzCgpgYGAKCiMgU3VwcGxlbWVudGFyeSBtZXRob2RzCgokfiQKCioqTEh+TX4gY3VsdHVyaW5nKioKCldlIG1haW50YWluZWQgdGhpcyBMSH5NfiBzdG9jayBpbiBvdXIgbGFib3JhdG9yeSBmb3IgMzIgZ2VuZXJhdGlvbnMgcHJpb3IgdG8gY3JlYXRpbmcgdGhlIGdlbm90eXBlcyByZXF1aXJlZCBmb3IgZXhwZXJpbWVudGFsIGV2b2x1dGlvbi4gV2UgY3VsdHVyZWQgTEh+TX4gYXQgMjVDLCB3aXRoIGEgMTYtOCBsaWdodC1kYXJrIGN5Y2xlIGFuZCByZWFyZWQgaW4gdmlhbHMgKDk1bW0geCAyNW1tKSBvbiBhIGNvcm4tbWVhbCwgeWVhc3QgYW5kIGRleHRyb3NlLWJhc2VkIGRpZXQgKHJlY2lwZSBpbiBUYWJsZSBTMTsgfjhjbTMgb2YgZm9vZCBtZWRpdW0gcGVyIHZpYWwpIHN1cHBsZW1lbnRlZCB3aXRoIGRyaWVkIHllYXN0LCBhdCBhIHBvcHVsYXRpb24gc2l6ZSBvZiBhdCBsZWFzdCA4MDAgYnJlZWRpbmcgaW5kaXZpZHVhbHMgYWNyb3NzIDI1IHZpYWxzICgxNiBmbGllcyBvZiBlYWNoIHNleCBwZXIgdmlhbCwgZm9sbG93aW5nIFJpY2UgX2V0IGFsXy4gMjAwNSkuIEVhY2ggZ2VuZXJhdGlvbiBiZWdpbnMgYnkgcG9vbGluZyB0aGUgb2Zmc3ByaW5nIHByb2R1Y2VkIGFjcm9zcyB0aGUgMjUgdmlhbHMgYW5kIHJhbmRvbWx5IGFzc29ydGluZyAxNiBmZW1hbGUtbWFsZSBwYWlycyB0byAyNSBuZXcgdmlhbHMuIFdlIHRoZW4gYWxsb3cgdGhlc2UgYnJlZWRpbmcgaW5kaXZpZHVhbHMgNDggaG91cnMgdG8gaW50ZXJhY3QgYW5kIG1hdGUsIGJlZm9yZSB0cmFuc2ZlcnJpbmcgdGhlbSB0byBhbm90aGVyIHNldCBvZiBuZXcgdmlhbHMuIEFmdGVyIDI0IGhvdXJzIG9mIGVnZy1sYXlpbmcsIHdlIGRpc2NhcmQgYWxsIGFkdWx0cywgYW5kIGFsbG93IGp1dmVuaWxlcyAxMiBkYXlzIHRvIGNvbXBldGUgZm9yIHJlc291cmNlcywgcHVwYXRlIGFuZCBlY2xvc2UgYXMgYWR1bHRzLiBXZSB0aGVuIGl0ZXJhdGl2ZWx5IHJlcGVhdCB0aGlzIHByb2Nlc3MgZWFjaCBnZW5lcmF0aW9uIHRvIG1haW50YWluIHRoZSBwb3B1bGF0aW9uLgoKJH4kCgoqKkNyZWF0aW5nIHRoZSBnZW5vdHlwZXMgdXNlZCBmb3IgZXhwZXJpbWVudGFsIGV2b2x1dGlvbioqCgpgYGB7cn0KaW1nIDwtIHJlYWRQTkcoIkZpZ3VyZV9TMS5wbmciKQogCmdyaWQucmFzdGVyKGltZykKYGBgCgoqKkZpZ3VyZSBTMSoqLiBDcm9zc2luZyBzY2hlbWUgdXNlZCB0byBpbnRlZ3JhdGUgdGhlIEdGUCBjb25zdHJ1Y3RzIGFuZCBfYXBeWEFeXyBtYXJrZWQgdHJhbnNsb2NhdGVkIHNlY29uZCBhbmQgdGhpcmQgY2hyb21vc29tZSBiYWxhbmNlcnMgaW50byB0aGUgTEh+TX4gZ2VuZXRpYyBiYWNrZ3JvdW5kLiBXZSByZXBsaWNhdGVkIHRoZSBjcm9zc2VzIDEyIHRpbWVzIHRvIHN1cHBseSB0aGUgZmxpZXMgdXNlZCBpbiBnZW5lcmF0aW9uIHplcm8gb2YgZXhwZXJpbWVudGFsIGV2b2x1dGlvbjsgNiB0aW1lcyB1c2luZyB0aGUgX1ViaV8gR0ZQIGNvbnN0cnVjdCBhbmQgNiB0aW1lcyB3aXRoIHRoZSBfM3hQXyBjb25zdHJ1Y3QuIEcgPSBnZW5lcmF0aW9uLgoKJH4kCgoqKlRhYmxlIFMxKiouIFJlY2lwZSBmb3IgZm9vZCBtZWRpdW0gdXNlZCBpbiBvdXIgZXhwZXJpbWVudC4gVGhlIHByb3ZpZGVkIHF1YW50aXRpZXMgbWFrZSB+IDEgbGl0cmUgb2YgZm9vZC4KCmBgYHtyfQp0aWJibGUoIkluZ3JlZGllbnRzIiA9IGMoIlNveSBmbG91ciIsICJDb3JubWVhbCIsICJZZWFzdCIsICJEZXh0cm9zZSIsICJBZ2FyIiwgIldhdGVyIiwgIlRlZ29zZXB0IiwgIkFjaWQgbWl4ICg0IG1MIG9ydGhvcGhvc3Bob3JpYyBhY2lkLCA0MSBtTCBwcm9waW9uaWMgYWNpZCwgNTUgbUwgd2F0ZXIgdG8gbWFrZSAxMDAgbUwpIiksCiAgICAgICAiUXVhbnRpdHkiID0gYygiMjAgZyIsICI3MyBnIiwgIjM1IGciLCAiNzUgZyIsICI2IGciLCAiMTAwMCBtTCIsICIxNyBtTCIsICIxNCBtTCIpKSAlPiUgCiAgcGFuZGVyKHNwbGl0LmNlbGwgPSA0MCwgc3BsaXQudGFibGUgPSBJbmYpCmBgYAoKJH4kCgojIEFuYWx5c2lzCgojIyBMb2FkIGluIHRoZSBkYXRhIAoKJH4kCgpgYGB7cn0KCmZpdG5lc3NfZGF0YSA8LSByZWFkX2NzdigiZGF0YS9TTENfZml0bmVzc19kYXRhLmNzdiIpICU+JSAKICBtdXRhdGUoRml0bmVzc192aWFsX0lEID0gYXMuZmFjdG9yKEZpdG5lc3NfdmlhbF9JRCksCiAgICAgICAgIEJsb2NrID0gYXMuZmFjdG9yKEJsb2NrKSwKICAgICAgICAgUG9wdWxhdGlvbiA9IGFzLmZhY3RvcihQb3B1bGF0aW9uKSwKICAgICAgICAgVHJlYXRtZW50ID0gYXMuZmFjdG9yKFRyZWF0bWVudCksCiAgICAgICAgIEdGUCA9IGFzLmZhY3RvcihHRlApLAogICAgICAgICBTZXggPSBhcy5mYWN0b3IoU2V4KSwKICAgICAgICAgUmVhcmluZ192aWFsID0gYXMuZmFjdG9yKFJlYXJpbmdfdmlhbCksCiAgICAgICAgIFRvdGFsX3JlZF9vZmZzcHJpbmcgPSBSZWRfZmVtYWxlX29mZnNwcmluZyArIFJlZF9tYWxlX29mZnNwcmluZywKICAgICAgICAgVG90YWxfYndfb2Zmc3ByaW5nID0gYndfZmVtYWxlX29mZnNwcmluZyArIGJ3X21hbGVfb2Zmc3ByaW5nLAogICAgICAgICBUb3RhbF9vZmZzcHJpbmcgPSBUb3RhbF9yZWRfb2Zmc3ByaW5nICsgVG90YWxfYndfb2Zmc3ByaW5nKSAlPiUgCiAgcmVuYW1lKEluaGVyaXRhbmNlX3RyZWF0bWVudCA9IFRyZWF0bWVudCkKCiMgQ3JlYXRlIGEgZnVuY3Rpb24gdG8gYnVpbGQgSFRNTCBzZWFyY2hhYmxlIHRhYmxlcwoKbXlfZGF0YV90YWJsZSA8LSBmdW5jdGlvbihkZil7CiAgZGF0YXRhYmxlKAogICAgZGYsIHJvd25hbWVzPUZBTFNFLAogICAgYXV0b0hpZGVOYXZpZ2F0aW9uID0gVFJVRSwKICAgIGV4dGVuc2lvbnMgPSBjKCJTY3JvbGxlciIsICAiQnV0dG9ucyIpLAogICAgb3B0aW9ucyA9IGxpc3QoCiAgICAgIGRvbSA9ICdCZnJ0aXAnLAogICAgICBkZWZlclJlbmRlcj1UUlVFLAogICAgICBzY3JvbGxYPVRSVUUsIHNjcm9sbFk9NDAwLAogICAgICBzY3JvbGxDb2xsYXBzZT1UUlVFLAogICAgICBidXR0b25zID0KICAgICAgICBsaXN0KCdwYWdlTGVuZ3RoJywgJ2NvbHZpcycsICdjc3YnLCBsaXN0KAogICAgICAgICAgZXh0ZW5kID0gJ3BkZicsCiAgICAgICAgICBwYWdlU2l6ZSA9ICdBNCcsCiAgICAgICAgICBvcmllbnRhdGlvbiA9ICdsYW5kc2NhcGUnLAogICAgICAgICAgZmlsZW5hbWUgPSAnZml0bmVzc19kYXRhJykpLAogICAgICBwYWdlTGVuZ3RoID0gNjkyCiAgICApCiAgKQp9CgoKbXlfZGF0YV90YWJsZShmaXRuZXNzX2RhdGEgJT4lIHNlbGVjdCgtQ29tbWVudCkpCgpgYGAKCioqQ29sdW1uIGV4cGxhbmF0aW9ucyoqCgpGaXRuZXNzX3ZpYWxfSUQ6IGEgdW5pcXVlIGlkZW50aWZpZXIgZm9yIGVhY2ggdHJpYWwgb2YgdGhlIGZpdG5lc3MgYXNzYXkuCgpCbG9jazogdGhlIGV4cGVyaW1lbnQgd2FzIHJ1biBpbiB0aHJlZSBkaXN0aW5jdCBibG9ja3MsIHVzaW5nIGZsaWVzIGZyb20gc2VwYXJhdGUgZ2VuZXJhdGlvbnMuCgpQb3B1bGF0aW9uOiB3ZSBtZWFzdXJlZCB0aGUgZml0bmVzcyBvZiBmbGllcyBmcm9tIDEyIGluZGVwZW5kZW50IHBvcHVsYXRpb25zIHRoYXQgY29udGFpbmVkIGF1dG9zb21lcyB0aGF0IGhhZCB1bmRlcmdvbmUgZXhwZXJpbWVudGFsIGV2b2x1dGlvbi4KCkluaGVyaXRhbmNlX3RyZWF0bWVudDogdGhlIHBvcHVsYXRpb25zIGNhcnJpZWQgYXV0b3NvbWVzIHRoYXQgaGFkIGJlZW4gZXhwb3NlZCB0byBvbmUgb2YgdGhyZWUgaW5oZXJpdGFuY2UgdHJlYXRtZW50cyBmb3IgMjAgZ2VuZXJhdGlvbnM6IGEgZmVtYWxlLWxpbWl0ZWQgaW5oZXJpdGFuY2UgdHJlYXRtZW50IHdoZXJlIGF1dG9zb21lcyB3ZXJlIGFsd2F5cyBwYXNzZWQgZnJvbSBtb3RoZXIgdG8gZGF1Z2h0ZXIsIGEgbWFsZS1saW1pdGVkIHRyZWF0bWVudCB3aGVyZSBhdXRvc29tZXMgd2VyZSBwYXNzZWQgZnJvbSBmYXRoZXIgdG8gc29uLCBhbmQgYSBjb250cm9sIGNvbmRpdGlvbiB3aGVyZSBpbmhlcml0YW5jZSB3YXMgdW5jb25zdHJhaW5lZC4KCkdGUDogdGhlIEdGUCBtYXJrZXIgY2FycmllZCBieSB0aGUgcG9wdWxhdGlvbi4gVUJJIGluZGljYXRlcyB0aGUgcHJlc2VuY2Ugb2YgYSB0cmFuc2dlbmUgdGhhdCBlbmNvZGVzIHViaXF1aXRvdXMgZXhwcmVzc2lvbiBvZiBHRlAsIHdoaWxlIDN4UCBpbmRpY2F0ZXMgdGhlIHByZXNlbmNlIG9mIGEgZGlmZmVyZW50IHRyYW5zZ2VuZSB0aGF0IGVuY29kZXMgdGhlIGV4cHJlc3Npb24gb2YgR0ZQIGluIHRoZSBvY2VsbGkuIAoKU2V4OiB0aGUgc2V4IG9mIHRoZSBpbmRpdmlkdWFscyB0aGF0IHdlIHdlcmUgbWVhc3VyaW5nIHRoZSBmaXRuZXNzIG9mLgoKUmVhcmluZ192aWFsOiB0aGUgdmlhbCB0aGUgdHJlYXRtZW50IGZsaWVzIHVzZWQgaW4gdGhlIHRyaWFsIGRldmVsb3BlZCBpbi4gVGhpcyB2YXJpYWJsZSBpcyBpbmNsdWRlZCB0byBjYXB0dXJlIHZhcmlhdGlvbiBleHBsYWluZWQgYnkgdGhlIHJlYXJpbmcgZW52aXJvbm1lbnQgZS5nLiBzbWFsbCBkaWZmZXJlbmNlcyBpbiBmb29kIG1vaXN0dXJlIGNvbnRlbnQgb3IgcXVhbnRpdHkuIE5vdGUgdGhhdCBmZW1hbGVzIGFuZCBtYWxlcyBjYW4gaGF2ZSB0aGUgc2FtZSByZWFyaW5nIHZpYWwgYXMgdGhlIHNleGVzIHdlcmUgcmVhcmVkIHRvZ2V0aGVyLgoKUmVkX2ZlbWFsZV9vZmZzcHJpbmc6IHRoZSBudW1iZXIgb2YgYWR1bHQgZmVtYWxlIG9mZnNwcmluZyBzaXJlZC9wcm9kdWNlZCBieSBmbGllcyBzb3VyY2VkIGZyb20gb25lIG9mIHRoZSAxMiBwb3B1bGF0aW9ucy4KClJlZF9tYWxlX29mZnNwcmluZzogdGhlIG51bWJlciBvZiBhZHVsdCBtYWxlIG9mZnNwcmluZyBzaXJlZC9wcm9kdWNlZCBieSBmbGllcyBzb3VyY2VkIGZyb20gb25lIG9mIHRoZSAxMiBwb3B1bGF0aW9ucy4KCmJ3X2ZlbWFsZV9vZmZzcHJpbmc6IHRoZSBudW1iZXIgb2YgYWR1bHQgZmVtYWxlIG9mZnNwcmluZyBzaXJlZC9wcm9kdWNlZCBieSB0aGUgY29tcGV0aXRvciBmbGllcyBpbiBvdXIgZml0bmVzcyBhc3NheS4gX2J3XyBpcyBhIHJlY2Vzc2l2ZSBhbGxlbGUgdGhhdCBlbmNvZGVzIGJyb3duIGV5ZSBjb2xvdXIuCgpid19tYWxlX29mZnNwcmluZzogdGhlIG51bWJlciBvZiBhZHVsdCBtYWxlIG9mZnNwcmluZyBzaXJlZC9wcm9kdWNlZCBieSB0aGUgY29tcGV0aXRvciBmbGllcyBpbiBvdXIgZml0bmVzcyBhc3NheS4gX2J3XyBpcyBhIHJlY2Vzc2l2ZSBhbGxlbGUgdGhhdCBlbmNvZGVzIGJyb3duIGV5ZSBjb2xvdXIuCgpUb3RhbF9yZWRfb2Zmc3ByaW5nOiB0aGUgdG90YWwgbnVtYmVyIChzZXhlcyBwb29sZWQpIG9mIGFkdWx0IG9mZnNwcmluZyBzaXJlZC9wcm9kdWNlZCBieSBmbGllcyBzb3VyY2VkIGZyb20gb25lIG9mIHRoZSAxMiBwb3B1bGF0aW9ucy4KClRvdGFsX2J3X29mZnNwcmluZzogdGhlIHRvdGFsIG51bWJlciAoc2V4ZXMgcG9vbGVkKSBvZiBhZHVsdCBvZmZzcHJpbmcgc2lyZWQvcHJvZHVjZWQgYnkgY29tcGV0aXRvciBmbGllcy4KClRvdGFsX29mZnNwcmluZzogdGhlIHRvdGFsIG51bWJlciAoc2V4ZXMgYW5kIGV5ZSBjb2xvdXJzIHBvb2xlZCkgb2YgYWR1bHQgb2Zmc3ByaW5nIGNvdW50ZWQgaW4gZWFjaCB2aWFsLgoKCiR+JAoKIyMgTW9kZWxsaW5nIGFwcHJvYWNoCgokfiQKCkZlbWFsZSBhbmQgbWFsZSBmaXRuZXNzIGFyZSBmdW5kYW1lbnRhbGx5IGRpZmZlcmVudCBjb25jZXB0cyAvIHRyYWl0cy4gVGhlcmUgYXJlIGFsc28gc2V2ZXJhbCBkaWZmZXJlbmNlcyBiZXR3ZWVuIG91ciBmZW1hbGUgYW5kIG1hbGUgZml0bmVzcyBhc3NheXMuIFRoZSBtYWpvciBkaWZmZXJlbmNlIGlzIHRoYXQgdGhlIG1hbGUgYXNzYXkgY29udGFpbnMgaGFsZiB0aGUgbnVtYmVyIG9mIGZlbWFsZXMgaW4gYW55IGdpdmVuIHZpYWwgdGhhbiBkb2VzIHRoZSBmZW1hbGUgYXNzYXkuIFRoZSBsb2dpYyBiZWhpbmQgdGhpcyBkZXNpZ24gY2hvaWNlIGlzIHRoYXQgc2V4dWFsbHkgc2VsZWN0ZWQgcHJvY2Vzc2VzIGFyZSBhIG1vcmUgaW1wb3J0YW50IGRldGVybWluYW50IG9mIG1hbGUgZml0bmVzcyB0aGFuIHRoZXkgYXJlIGZlbWFsZSBmaXRuZXNzLCBzbyBhbnkgZml0bmVzcyBkaWZmZXJlbmNlcyBtYXkgb25seSBiZSBvYnNlcnZlZCB3aGVuIGNvbXBldGl0aW9uIGZvciBmZXJ0aWxpc2F0aW9ucyBpcyBoaWdoLiAKCkZvciB0aGVzZSByZWFzb25zLCB3ZSBjaG9vc2UgdG8gc3BsaXQgdGhlIGRhdGEgdXAgYW5kIG1vZGVsIGZlbWFsZSBhbmQgbWFsZSBmaXRuZXNzIHNlcGFyYXRlbHkuCgpgYGB7cn0KZmVtYWxlX2ZpdG5lc3MgPC0gCiAgZml0bmVzc19kYXRhICU+JQogIGZpbHRlcihTZXggPT0gIkZlbWFsZSIpCgptYWxlX2ZpdG5lc3MgPC0gCiAgZml0bmVzc19kYXRhICU+JQogIGZpbHRlcihTZXggPT0gIk1hbGUiKSAlPiUgCiAgbXV0YXRlKHByb3BfcmVkID0gVG90YWxfcmVkX29mZnNwcmluZyAvIFRvdGFsX29mZnNwcmluZykKICAKYGBgCgpXZSBmaXQgdGhlIGZvbGxvd2luZyBmaXhlZCBhbmQgcmFuZG9tIGVmZmVjdHMgdG8gbW9kZWwgZmVtYWxlIGFuZCBtYWxlIGZpdG5lc3MuIE91ciBhaW0gaXMgdG8gZXN0aW1hdGUgdGhlIGNhdXNhbCBlZmZlY3QgdGhhdCBgSW5oZXJpdGFuY2VfdHJlYXRtZW50IChJKWAgaGFzIG9uIGBmaXRuZXNzIChGKWAuCgoqKkZpeGVkIGVmZmVjdHMqKgoKYEluaGVyaXRhbmNlX3RyZWF0bWVudCAoSSlgOiB0aGlzIGlzIHRoZSBpbmhlcml0YW5jZSByZWdpbWUgdGhhdCB0aGUgYXV0b3NvbWVzIGNhcnJpZWQgYnkgZWFjaCBvZiB0aGUgcG9wdWxhdGlvbnMgd2VyZSBzdWJqZWN0IHRvIGZvciAyMCBnZW5lcmF0aW9ucy4gVGhlcmUgYXJlIHRocmVlIGxldmVsczogcG9wdWxhdGlvbnMgY2FycnlpbmcgZmVtYWxlLWFkYXB0ZWQgYXV0b3NvbWVzLCBwb3B1bGF0aW9ucyBjb250YWluaW5nIG1hbGUtYWRhcHRlZCBhdXRvc29tZXMgYW5kIHBvcHVsYXRpb25zIGNhcnJ5aW5nIGNvbnRyb2wgYXV0b3NvbWVzIHRoYXQgZXhwZXJpZW5jZWQgYW4gdW5tYW5pcHVsYXRlZCBpbmhlcml0YW5jZSByZWdpbWUuIFdlIGFyZSBkZXNpZ25pbmcgb3VyIG1vZGVsIHRvIHRlc3QgZm9yIGEgY2F1c2FsIGVmZmVjdCBvZiB0aGlzIHZhcmlhYmxlLgoKX01lZGlhdG9yIHZhcmlhYmxlc18KCmBCbG9jayAoQilgOiBmaXRuZXNzIG1pZ2h0IGRpZmZlciBiZXR3ZWVuIHRoZSB0aHJlZSBkaXN0aW5jdCBibG9ja3Mgd2Ugc3BsaXQgb3VyIGV4cGVyaW1lbnQgdXAgaW50by4gQmxvY2tzIGRpZmZlcmVkIHRlbXBvcmFsbHksIHVzZWQgZmxpZXMgZnJvbSBkaWZmZXJlbnQgZ2VuZXJhdGlvbnMgYW5kIGRpZmZlcmVudCBiYXRjaGVzIG9mIGZvb2QuIEl0IGlzIGFsc28gcG9zc2libGUgdGhhdCB0aGVyZSB3ZXJlIG1pbm9yIGZsdWN0dWF0aW9ucyBpbiB0aGUgbGlnaHRpbmcgYW5kIHRlbXBlcmF0dXJlIGVudmlyb25tZW50IGV4cGVyaWVuY2VkIGR1cmluZyBkZXZlbG9wbWVudCBiZXR3ZWVuIGJsb2Nrcy4gRWFjaCBvZiB0aGVzZSB2YXJpYWJsZXMgbWF5IGludHJvZHVjZSB2YXJpYXRpb24gaW50byBvdXIgZml0bmVzcyBtZWFzdXJlbWVudHMsIHRoYXQgY2FuIGJlIGFjY291bnRlZCBmb3IgYnkgaW5jbHVkaW5nIHRoZSBgQmxvY2tgIHZhcmlhYmxlIGluIG91ciBtb2RlbC4KCmBHRlAgKEcpYDogaXQgaXMgcG9zc2libGUgdGhhdCBmaXRuZXNzIG1heSBiZSBhZmZlY3RlZCBieSB0aGUgR0ZQIHRyYW5zZ2VuZSBjYXJyaWVkIGJ5IGVhY2ggcG9wdWxhdGlvbi4gRm9yIGV4YW1wbGUsIG9uZSBjb3VsZCBpbWFnaW5lIHRoYXQgYW55IHVuaW50ZW5kZWQgZml0bmVzcyBlZmZlY3RzIG9mIGEgdHJhbnNnZW5lIG1pZ2h0IGJlIG9mIGdyZWF0ZXIgbWFnbml0dWRlIGlmIGl0IGlzIGV4cHJlc3NlZCBpbiBhIGxhcmdlciBwcm9wb3J0aW9uIG9mIHRpc3N1ZXMsIGFzIGlzIHRoZSBjYXNlIGZvciB0aGUgX1VCSV8gdHJhbnNnZW5lIHZlcnN1cyB0aGUgXzN4UF8gdHJhbnNnZW5lLiBOb3RlIHRoYXQgZWFjaCBHRlAgdHlwZSBpcyBjYXJyaWVkIGJ5IGFuIGVxdWFsIG51bWJlciBvZiBwb3B1bGF0aW9ucyBmcm9tIGVhY2ggb2YgdGhlIHRocmVlIGV2b2x1dGlvbmFyeSB0cmVhdG1lbnRzLgoKKipWYXJ5aW5nL1JhbmRvbSBlZmZlY3RzKioKCmBQb3B1bGF0aW9uIChQKWA6IG91ciBkZXNpZ24gY29udGFpbmVkIDEyIGluZGVwZW5kZW50IHBvcHVsYXRpb25zIG9mIGF1dG9zb21lcyB0aGF0IG9yaWdpbmF0ZWQgZnJvbSBhIHNpbmdsZSBvdXRicmVkIGxhYm9yYXRvcnkgZmx5IHBvcHVsYXRpb24uIFRoZSBwb3B1bGF0aW9ucyB3ZXJlIHNwbGl0IGFuZCBhdXRvc29tZXMgZnJvbSBlYWNoIHdlcmUgc3ViamVjdGVkIHRvIG9uZSBvZiB0aGUgdGhyZWUgZXZvbHV0aW9uIHRyZWF0bWVudHMgZm9yIDIwIGdlbmVyYXRpb25zLiA0IHBvcHVsYXRpb25zIGV4cGVyaWVuY2VkIGEgZmVtYWxlLWxpbWl0ZWQgaW5oZXJpdGFuY2UgcmVnaW1lLCA0IGEgbWFsZS1saW1pdGVkIHJlZ2ltZSBhbmQgNCBhbiB1bmxpbWl0ZWQgb3IgY29udHJvbCByZWdpbWUuIAoKYFJlYXJpbmdfdmlhbCAoUilgOiB0aGUgdmlhbCBpbmRpdmlkdWFsIGZsaWVzIGRldmVsb3BlZCB3aXRoaW4gbWF5IGludHJvZHVjZSBmdXJ0aGVyIHZhcmlhdGlvbiBpbnRvIG91ciByZXNwb25zZSB2YXJpYWJsZS4gTGlrZSBgQmxvY2tgIHRoaXMgdmFyaWFibGUgY29udHJvbHMgZm9yIG1pY3JvLWVudmlyb25tZW50YWwgdmFyaWF0aW9uLgoKJH4kCgoqKkFjY291bnRpbmcgZm9yIG92ZXItZGlzcGVyc2lvbioqCgpUaGUgZGF0YSBpcyBvdmVyLWRpc3BlcnNlZCB3aXRoIHNldmVyYWwgaGlnaGx5IGluZmx1ZW50aWFsIChvdXRsaWVyKSBvYnNlcnZhdGlvbnMgdGhhdCBoYXZlIGxhcmdlIGVmZmVjdHMgb24gb3VyIHBvc3RlcmlvciBwcmVkaWN0aW9uLiBUbyBjb21iYXQgdGhpcywgd2UgZml0IG1vZGVscyBmb2xsb3dpbmcgdGhlIGBiZXRhYmlub21pYWxgIGRpc3RyaWJ1dGlvbiBmYW1pbHksIGFzIHRoaXMgaXMgYmV0dGVyIGVxdWlwcGVkIHRvIGRlYWwgd2l0aCBleHRyZW1lIHZhbHVlcyBhdCB0aGUgdGFpbHMgaS5lLiBvdmVyZGlzcGVyc2lvbi4KCkhvd2V2ZXIsIHRoZSBiZXRhLWJpbm9taWFsIGlzIG5vdCBhIG5hdGl2ZSBmYW1pbHkgaW4gYGJybXNgLCB3ZSBuZWVkIHRvIGNyZWF0ZSB0aGUgZGlzdHJpYnV0aW9uIGZhbWlseSB1c2luZyB0aGUgYGN1c3RvbV9mYW1pbHkoKWAgZnVuY3Rpb24uIFRoZSBjb2RlIGJlbG93IGlzIHRha2VuIGRpcmVjdGx5IGZyb20gdGhlIGBicm1zX2N1c3RvbWZhbWlsaWVzYCB2aWduZXR0ZSwgd2hpY2ggY2FuIGJlIHZpZXdlZCBbaGVyZV0oaHR0cHM6Ly9jcmFuLnItcHJvamVjdC5vcmcvd2ViL3BhY2thZ2VzL2JybXMvdmlnbmV0dGVzL2JybXNfY3VzdG9tZmFtaWxpZXMuaHRtbCkuCgpgYGB7cn0KYmV0YV9iaW5vbWlhbDIgPC0gY3VzdG9tX2ZhbWlseSgKICAiYmV0YV9iaW5vbWlhbDIiLCBkcGFycyA9IGMoIm11IiwgInBoaSIpLAogIGxpbmtzID0gYygibG9naXQiLCAibG9nIiksIGxiID0gYyhOQSwgMiksIAogICMgbm90ZSB0aGF0IHdlIHNldCB0aGUgbG93ZXIgYm91bmQgdG8gMiwgZm9sbG93aW5nIE1jRWxyZWF0aCwgcmF0aGVyIHRoYW4gQnVlcmtuZXIuIFRoaXMgbWVhbnMgdGhhdCB0aGUgbW9zdCBjb25zZXJ2YXRpdmUgZXN0aW1hdGUgZm9yIHBoaSB3ZSBnZXQgaXMgYSBmbGF0IGV4cGVjdGF0aW9uIGJldHdlZW4gMCBhbmQgMQogIHR5cGUgPSAiaW50IiwgdmFycyA9ICJ2aW50MVtuXSIKKQoKCnN0YW5fZnVucyA8LSAiCiAgcmVhbCBiZXRhX2Jpbm9taWFsMl9scG1mKGludCB5LCByZWFsIG11LCByZWFsIHBoaSwgaW50IFQpIHsKICAgIHJldHVybiBiZXRhX2Jpbm9taWFsX2xwbWYoeSB8IFQsIG11ICogcGhpLCAoMSAtIG11KSAqIHBoaSk7CiAgfQogIGludCBiZXRhX2Jpbm9taWFsMl9ybmcocmVhbCBtdSwgcmVhbCBwaGksIGludCBUKSB7CiAgICByZXR1cm4gYmV0YV9iaW5vbWlhbF9ybmcoVCwgbXUgKiBwaGksICgxIC0gbXUpICogcGhpKTsKICB9CiIKCnN0YW52YXJzIDwtIHN0YW52YXIoc2NvZGUgPSBzdGFuX2Z1bnMsIGJsb2NrID0gImZ1bmN0aW9ucyIpCgpgYGAKCiR+JAoKIyMgRmVtYWxlIGZpdG5lc3MKCiR+JAoKVG8gZXN0aW1hdGUgdGhlIGZpdG5lc3Mgb2YgZmVtYWxlcyBjYXJyeWluZyBlYWNoIG9mIHRoZSB0aHJlZSBhdXRvc29tZSB0eXBlcywgd2UgcGxhY2VkIHRocmVlIGV4cGVyaW1lbnRhbCBmZW1hbGVzIGludG8gYSB5ZWFzdGVkIHZpYWwgd2l0aCB0aHJlZSBmZW1hbGUgY29tcGV0aXRvcnMgdGhhdCBjYXJyaWVkIHRoZSBfYndfIG11dGF0aW9uLiBXZSB0aGVuIGludHJvZHVjZWQgc2l4IG1hbGVzIHRoYXQgYWxzbyBjYXJyaWVkIHRoZSBfYndfIG11dGF0aW9uLiBXZSBhbGxvd2VkIHRoZW0gdG8gbWF0ZSBhbmQgb3ZpcG9zaXQgZm9yIHRocmVlIGRheXMsIHRoZW4gcmVtb3ZlZCBhbGwgYWR1bHRzIGZyb20gdGhlIHZpYWwuIDEyIGRheXMgbGF0ZXIgd2UgY291bnRlZCBhbGwgb2YgdGhlIGFkdWx0IHByb2dlbnkgaW4gdGhlIHZpYWwgYW5kIHNjb3JlZCB0aGVtIGZvciBleWUtY29sb3VyLiBQcm9nZW55IHdpdGggcmVkIGV5ZXMgd2VyZSBwcm9kdWNlZCBieSB0aGUgZXhwZXJpbWVudGFsIGZlbWFsZXMgKCBfYndfIGlzIHJlY2Vzc2l2ZSkgYW5kIHByb2dlbnkgd2l0aCBicm93biBleWVzIHdlcmUgcHJvZHVjZWQgYnkgdGhlIGNvbXBldGl0b3IgZmVtYWxlcy4gV2UgY2FsY3VsYXRlZCBmaXRuZXNzIGFzIHRoZSBwcm9wb3J0aW9uIG9mIHJlZCBleWVkIG9mZnNwcmluZyBpbiB0aGUgdmlhbC4gCgpXZSBwcmVzZW50IHRoZSBmaXhlZCBlZmZlY3RzIGZyb20gdGhlIG1vZGVsOgoKJH4kCgpgYGB7cn0KZmVtYWxlX2ZpdG5lc3NfbW9kZWwgPC0KICBicm0oVG90YWxfcmVkX29mZnNwcmluZyB8IHZpbnQoVG90YWxfb2Zmc3ByaW5nKSB+IDEgKyBJbmhlcml0YW5jZV90cmVhdG1lbnQgKyBCbG9jayArIEdGUCArICgxfFBvcHVsYXRpb24pICsgKDF8UmVhcmluZ192aWFsKSwKICAgICAgZGF0YSA9IGZlbWFsZV9maXRuZXNzLCBmYW1pbHkgPSBiZXRhX2Jpbm9taWFsMiwgCiAgICAgIHByaW9yID0gYyhwcmlvcihub3JtYWwoMCwgMSksIGNsYXNzID0gSW50ZXJjZXB0KSwgIyB0aGlzIHNldHMgdGhlIHByaW9yIG1lYW4gYXQgMC41IHJlbGF0aXZlIGZpdG5lc3MKICAgICAgICAgICAgICAgIHByaW9yKG5vcm1hbCgwLCAxLjUpLCBjbGFzcyA9IGIpLAogICAgICAgICAgICAgICAgcHJpb3IoZXhwb25lbnRpYWwoMSksIGNsYXNzID0gcGhpKSksCiAgICAgIGl0ZXIgPSA4MDAwLCB3YXJtdXAgPSA0MDAwLCBjaGFpbnMgPSA0LCBjb3JlcyA9IDQsCiAgICAgIGNvbnRyb2wgPSBsaXN0KGFkYXB0X2RlbHRhID0gMC45OCwgbWF4X3RyZWVkZXB0aCA9IDEwKSwKICAgICAgc2VlZCA9IDIsIHN0YW52YXJzID0gc3RhbnZhcnMsIGZpbGUgPSAiRml0cy9mZW1hbGVfZml0bmVzcy5tb2RlbCIpCgpmaXhlZihmZW1hbGVfZml0bmVzc19tb2RlbCkgJT4lIAogIGthYmxlKGRpZ2l0cyA9IDMpICU+JSAKICBrYWJsZV9zdHlsaW5nKCkKCmBgYAoKV2UgbmVlZCB0byB3cml0ZSBzb21lIGFkZGl0aW9uYWwgY29kZSB0byBnZXQgc29tZSBwb3N0IHByb2Nlc3Npbmcgc3R1ZmYgaS5lLiBMT08gdG8gd29yay4gQ29kZSBjb3VydGVzeSBvZiB0aGUgYGJybXNfY3VzdG9tZmFtaWxpZXNgIHZpZ25ldHRlLCB3aGljaCBjYW4gYmUgdmlld2VkIFtoZXJlXShodHRwczovL2NyYW4uci1wcm9qZWN0Lm9yZy93ZWIvcGFja2FnZXMvYnJtcy92aWduZXR0ZXMvYnJtc19jdXN0b21mYW1pbGllcy5odG1sKS4KCmBgYHtyLCBpbmNsdWRlPUZBTFNFfQojIHdlIG5lZWQgdG8gd3JpdGUgc29tZSBhZGRpdGlvbmFsIGNvZGUgdG8gZ2V0IHNvbWUgcG9zdC1wcm9jZXNzaW5nIHN0dWZmIHRvIHdvcmsKCmV4cG9zZV9mdW5jdGlvbnMoZmVtYWxlX2ZpdG5lc3NfbW9kZWwsIHZlY3Rvcml6ZSA9IFRSVUUpCgoKbG9nX2xpa19iZXRhX2Jpbm9taWFsMiA8LSBmdW5jdGlvbihpLCBwcmVwKSB7CiAgbXUgPC0gYnJtczo6Z2V0X2RwYXIocHJlcCwgIm11IiwgaSA9IGkpCiAgcGhpIDwtIGJybXM6OmdldF9kcGFyKHByZXAsICJwaGkiLCBpID0gaSkKICB0cmlhbHMgPC0gcHJlcCRkYXRhJHZpbnQxW2ldCiAgeSA8LSBwcmVwJGRhdGEkWVtpXQogIGJldGFfYmlub21pYWwyX2xwbWYoeSwgbXUsIHBoaSwgdHJpYWxzKQp9Cgpwb3N0ZXJpb3JfcHJlZGljdF9iZXRhX2Jpbm9taWFsMiA8LSBmdW5jdGlvbihpLCBwcmVwLCAuLi4pIHsKICBtdSA8LSBicm1zOjpnZXRfZHBhcihwcmVwLCAibXUiLCBpID0gaSkKICBwaGkgPC0gYnJtczo6Z2V0X2RwYXIocHJlcCwgInBoaSIsIGkgPSBpKQogIHRyaWFscyA8LSBwcmVwJGRhdGEkdmludDFbaV0KICBiZXRhX2Jpbm9taWFsMl9ybmcobXUsIHBoaSwgdHJpYWxzKQp9Cgpwb3N0ZXJpb3JfZXByZWRfYmV0YV9iaW5vbWlhbDIgPC0gZnVuY3Rpb24ocHJlcCkgewogIG11IDwtIGJybXM6OmdldF9kcGFyKHByZXAsICJtdSIpCiAgdHJpYWxzIDwtIHByZXAkZGF0YSR2aW50MQogIHRyaWFscyA8LSBtYXRyaXgodHJpYWxzLCBucm93ID0gbnJvdyhtdSksIG5jb2wgPSBuY29sKG11KSwgYnlyb3cgPSBUUlVFKQogIG11ICogdHJpYWxzCn0KYGBgCgpSdW4gTE9PIHRvIHNlZSBpZiB3ZSd2ZSBlZmZlY3RpdmVseSBtb2RlbGxlZCBvdmVyIGRpc3BlcnNpb24uCgpgYGB7cn0KCmZlbWFsZV9maXRuZXNzX21vZGVsIDwtIGFkZF9jcml0ZXJpb24oZmVtYWxlX2ZpdG5lc3NfbW9kZWwsIGNyaXRlcmlvbiA9ICJsb28iLCBmaWxlID0gIkZpdHMvZmVtYWxlX2ZpdG5lc3MubW9kZWwiKQoKbG9vKGZlbWFsZV9maXRuZXNzX21vZGVsKQoKYGBgCgpUaGUgYmV0YS1iaW5vbWlhbCBtb2RlbCBsb29rcyBnb29kLiBJdCByZXR1cm5zIG5vIHBvaW50cyB3aXRoIGhpZ2ggcGFyZXRvIGsgdmFsdWVzLgoKQ29uZHVjdCBhIHBvc3RlcmlvciBwcmVkaWN0aXZlIGNoZWNrIHRvIGNvbmZpcm0gb3VyIG1vZGVsIGlzIGRvaW5nIHdoYXQgd2Ugd2FudCBpdCB0by4KCmBgYHtyfQpwcF9jaGVjayhmZW1hbGVfZml0bmVzc19tb2RlbCwgdHlwZSA9ICJoaXN0IiwgbmRyYXdzID0gMTEsIGJpbndpZHRoID0gMTApICsKICB0aGVtZV9taW5pbWFsKCkgKwogIHRoZW1lKHBhbmVsLmJhY2tncm91bmQgPSBlbGVtZW50X2JsYW5rKCkpCmBgYAoKVGhlIHBvc3RlcmlvciBwcmVkaWN0aXZlIGRpc3RyaWJ1dGlvbiByZWNhcGl0dWxhdGVzIG91ciByYXcgZGF0YSBxdWl0ZSB3ZWxsLCBpbmRpY2F0aW5nIHRoZSBtb2RlbCBpcyBtYWtpbmcgc2Vuc2libGUgcHJlZGljdGlvbnMuCgokfiQKCiMjIyBEZXJpdmUgcHJlZGljdGlvbnMgZnJvbSB0aGUgcG9zdGVyaW9yCgpHZXQgcHJlZGljdGlvbnMgZnJvbSB0aGUgbW9kZWwKCioqVGFibGUgUzIqKi4gRXN0aW1hdGVkIGZlbWFsZSBmaXRuZXNzIGZvciBmbGllcyBjYXJyeWluZyBhdXRvc29tZXMgZGVyaXZlZCBmcm9tIGVhY2ggb2YgdGhlIHRocmVlIGluaGVyaXRhbmNlIHJlZ2ltZXMuCgpgYGB7cn0KCmRyYXdzIDwtIGFzX2RyYXdzX2RmKGZlbWFsZV9maXRuZXNzX21vZGVsKQoKZHJhd3NfZmVtYWxlIDwtCiAgZHJhd3MgICU+JSAKICBtdXRhdGUoYEZlbWFsZS1saW1pdGVkYCA9IGludl9sb2dpdF9zY2FsZWQoYl9JbnRlcmNlcHQgKyBiX0luaGVyaXRhbmNlX3RyZWF0bWVudEZlbWFsZV9saW1pdGVkKSwKICAgICAgICAgYE1hbGUtbGltaXRlZGAgPSBpbnZfbG9naXRfc2NhbGVkKGJfSW50ZXJjZXB0ICsgYl9Jbmhlcml0YW5jZV90cmVhdG1lbnRNYWxlX2xpbWl0ZWQpLAogICAgICAgICBDb250cm9sID0gaW52X2xvZ2l0X3NjYWxlZChiX0ludGVyY2VwdCkpICU+JSAKICBzZWxlY3QoYEZlbWFsZS1saW1pdGVkYCwgQ29udHJvbCwgYE1hbGUtbGltaXRlZGApICU+JSAKICAgIHBpdm90X2xvbmdlcihjb2xzID0gYyhgRmVtYWxlLWxpbWl0ZWRgLCBDb250cm9sLCBgTWFsZS1saW1pdGVkYCksCiAgICAgICAgICAgICAgICAgbmFtZXNfdG8gPSAiSW5oZXJpdGFuY2UgdHJlYXRtZW50IikgJT4lIAogIHJlbmFtZShwcm9wX2ZvY2FsX29mZnNwcmluZyA9IHZhbHVlKSAlPiUgCiAgYXJyYW5nZShgSW5oZXJpdGFuY2UgdHJlYXRtZW50YCkKCmRyYXdzX2ZlbWFsZSAlPiUgCiAgZ3JvdXBfYnkoYEluaGVyaXRhbmNlIHRyZWF0bWVudGApICU+JSAKICBzdW1tYXJpc2UoYEVzdGltYXRlZCBwcm9wLiBvZiBvZmZzcHJpbmcgcHJvZHVjZWRgID0gbWVhbihwcm9wX2ZvY2FsX29mZnNwcmluZyksCiAgICAgICAgICAgIGAyLjUlYCA9IHF1YW50aWxlKHByb3BfZm9jYWxfb2Zmc3ByaW5nLCBwcm9icyA9IDAuMDI1KSwKICAgICAgICAgICAgYDk3LjUlYCA9IHF1YW50aWxlKHByb3BfZm9jYWxfb2Zmc3ByaW5nLCBwcm9icyA9IDAuOTc1KSkgJT4lIAogIHBhbmRlcihzcGxpdC5jZWxsID0gNDAsIHNwbGl0LnRhYmxlID0gSW5mLCByb3VuZCA9IDMpCgpgYGAKCioqVGFibGUgUzMqKi4gRGlmZmVyZW5jZXMgaW4gZmVtYWxlIGZpdG5lc3MgYmV0d2VlbiBlYWNoIG9mIHRoZSB0aHJlZSBpbmhlcml0YW5jZSByZWdpbWVzLgoKYGBge3J9CiMgRmluZCBkaWZmZXJlbmNlcyBhbmQgdmlzdWFsaXNlIGluIHRhYmxlCgpkcmF3c19kaWZmIDwtIGRyYXdzICAlPiUgCiAgbXV0YXRlKGBGZW1hbGUtbGltaXRlZGAgPSBpbnZfbG9naXRfc2NhbGVkKGJfSW50ZXJjZXB0ICsgYl9Jbmhlcml0YW5jZV90cmVhdG1lbnRGZW1hbGVfbGltaXRlZCksCiAgICAgICAgIGBNYWxlLWxpbWl0ZWRgID0gaW52X2xvZ2l0X3NjYWxlZChiX0ludGVyY2VwdCArIGJfSW5oZXJpdGFuY2VfdHJlYXRtZW50TWFsZV9saW1pdGVkKSwKICAgICAgICAgQ29udHJvbCA9IGludl9sb2dpdF9zY2FsZWQoYl9JbnRlcmNlcHQpKSAlPiUKICBtdXRhdGUoYEZlbWFsZSAtIENvbnRyb2xgID0gYEZlbWFsZS1saW1pdGVkYCAtIENvbnRyb2wsCiAgICAgICAgIGBNYWxlIC0gQ29udHJvbGAgPSBgTWFsZS1saW1pdGVkYCAtIENvbnRyb2wsCiAgICAgICAgIGBGZW1hbGUgLSBNYWxlYCA9IGBGZW1hbGUtbGltaXRlZGAgLSBgTWFsZS1saW1pdGVkYCkgJT4lIAogIHNlbGVjdChgRmVtYWxlIC0gQ29udHJvbGAsIGBNYWxlIC0gQ29udHJvbGAsIGBGZW1hbGUgLSBNYWxlYCkKCnJiaW5kKAogIGRyYXdzX2RpZmYgJT4lIAogICAgc3VtbWFyaXNlKGBEaWZmIGluIG9mZnNwcmluZyBwcm9kdWNlZCBwZXIgMTAwYCA9IG1lYW4oYE1hbGUgLSBDb250cm9sYCkqMTAwLAogICAgICAgICAgICAgIGAyLjUlYCA9IHF1YW50aWxlKGBNYWxlIC0gQ29udHJvbGAsIHByb2JzID0gMC4wMjUpICoxMDAsCiAgICAgICAgICAgICAgYDk3LjUlYCA9IHF1YW50aWxlKGBNYWxlIC0gQ29udHJvbGAsIHByb2JzID0gMC45NzUpICoxMDApICU+JSAKICAgIG11dGF0ZShDb250cmFzdCA9ICJNYWxlIGluaGVyaXRlZCAtIENvbnRyb2wiKSwKICAKICBkcmF3c19kaWZmICU+JSAKICAgIHN1bW1hcmlzZShgRGlmZiBpbiBvZmZzcHJpbmcgcHJvZHVjZWQgcGVyIDEwMGAgPSBtZWFuKGBGZW1hbGUgLSBDb250cm9sYCkqMTAwLAogICAgICAgICAgICAgIGAyLjUlYCA9IHF1YW50aWxlKGBGZW1hbGUgLSBDb250cm9sYCwgcHJvYnMgPSAwLjAyNSkgKjEwMCwKICAgICAgICAgICAgICBgOTcuNSVgID0gcXVhbnRpbGUoYEZlbWFsZSAtIENvbnRyb2xgLCBwcm9icyA9IDAuOTc1KSAqMTAwKSAlPiUgCiAgICBtdXRhdGUoQ29udHJhc3QgPSAiRmVtYWxlIGluaGVyaXRlZCAtIENvbnRyb2wiKSwKICAKICBkcmF3c19kaWZmICU+JSAKICAgIHN1bW1hcmlzZShgRGlmZiBpbiBvZmZzcHJpbmcgcHJvZHVjZWQgcGVyIDEwMGAgPSBtZWFuKGBGZW1hbGUgLSBNYWxlYCkqMTAwLAogICAgICAgICAgICAgIGAyLjUlYCA9IHF1YW50aWxlKGBGZW1hbGUgLSBNYWxlYCwgcHJvYnMgPSAwLjAyNSkgKjEwMCwKICAgICAgICAgICAgICBgOTcuNSVgID0gcXVhbnRpbGUoYEZlbWFsZSAtIE1hbGVgLCBwcm9icyA9IDAuOTc1KSAqMTAwKSAlPiUgCiAgICBtdXRhdGUoQ29udHJhc3QgPSAiRmVtYWxlIGluaGVyaXRlZCAtIE1hbGUgaW5oZXJpdGVkIikKKSAlPiUgCiAgc2VsZWN0KENvbnRyYXN0LCBgRGlmZiBpbiBvZmZzcHJpbmcgcHJvZHVjZWQgcGVyIDEwMGAsIGAyLjUlYCwgYDk3LjUlYCkgJT4lIAogIHBhbmRlcihzcGxpdC5jZWxsID0gNDAsIHNwbGl0LnRhYmxlID0gSW5mLCByb3VuZCA9IDIpCgpgYGAKCioqVGhlIGVmZmVjdHMgb2YgdGhlIGJsb2NrIGFuZCBHRlAgcHJlZGljdG9ycyoqCgoqKlRhYmxlIFM0KiouIFRoZSBlZmZlY3RzIG9mIHRoZSBmaXhlZCBwcmVkaWN0b3IgdmFyaWFibGVzIG9uIGZlbWFsZSBmaXRuZXNzIHRoYXQgYXJlIG5vdCBkaXJlY3RseSByZWxhdGVkIHRvIGludHJhbG9jdXMgc2V4dWFsIGNvbmZsaWN0LiBGZW1hbGUgZml0bmVzcyBtZWFzdXJlZCBpbiBCbG9jayAxIHdhcyBoaWdoZXIgdGhhbiB0aGF0IG1lYXN1cmVkIGluIEJsb2NrcyAyIGFuZCAzLiBGZW1hbGVzIGNhcnJ5aW5nIGF1dG9zb21lcyBtYXJrZWQgd2l0aCAzeFAgR0ZQIGhhZCBoaWdoZXIgZml0bmVzcyB0aGFuIHRob3NlIGV4cHJlc3NpbmcgVUJJIEdGUC4KCmBgYHtyfQogIApkcmF3c19kaWZmX290aGVyIDwtIGRyYXdzICAlPiUgCiAgc2VsZWN0KGJfSW50ZXJjZXB0LCBiX0Jsb2NrMiwgYl9CbG9jazMsIGJfR0ZQVUJJKSAlPiUgCiAgbXV0YXRlKGBCbG9jayAxLCAzeFBgID0gaW52X2xvZ2l0X3NjYWxlZChiX0ludGVyY2VwdCksCiAgICAgICAgIGBCbG9jayAyYCA9IGludl9sb2dpdF9zY2FsZWQoYl9JbnRlcmNlcHQgKyBiX0Jsb2NrMiksCiAgICAgICAgIGBCbG9jayAzYCA9IGludl9sb2dpdF9zY2FsZWQoYl9JbnRlcmNlcHQgKyBiX0Jsb2NrMyksCiAgICAgICAgIFVCSSA9IGludl9sb2dpdF9zY2FsZWQoYl9JbnRlcmNlcHQgKyBiX0dGUFVCSSkpICU+JQogIG11dGF0ZShgQmxvY2sgMSAtIEJsb2NrIDJgID0gYEJsb2NrIDEsIDN4UGAgLSBgQmxvY2sgMmAsCiAgICAgICAgIGBCbG9jayAxIC0gQmxvY2sgM2AgPSBgQmxvY2sgMSwgM3hQYCAtIGBCbG9jayAzYCwKICAgICAgICAgYDN4UCAtIFVCSWAgPSBgQmxvY2sgMSwgM3hQYCAtIFVCSSkgJT4lIAogIHNlbGVjdChgQmxvY2sgMSAtIEJsb2NrIDJgLCBgQmxvY2sgMSAtIEJsb2NrIDNgLCBgM3hQIC0gVUJJYCkKCiMgRmluZCBkaWZmZXJlbmNlcyBhbmQgdmlzdWFsaXNlIGluIHRhYmxlCgpyYmluZCgKZHJhd3NfZGlmZl9vdGhlciAlPiUgCiAgc3VtbWFyaXNlKGBEaWZmIGluIG9mZnNwcmluZyBwcm9kdWNlZCBwZXIgMTAwYCA9IG1lYW4oYEJsb2NrIDEgLSBCbG9jayAyYCkqMTAwLAogICAgICAgICAgICBgMi41JWAgPSBxdWFudGlsZShgQmxvY2sgMSAtIEJsb2NrIDJgLCBwcm9icyA9IDAuMDI1KSAqMTAwLAogICAgICAgICAgICBgOTcuNSVgID0gcXVhbnRpbGUoYEJsb2NrIDEgLSBCbG9jayAyYCwgcHJvYnMgPSAwLjk3NSkgKjEwMCkgJT4lIAogIG11dGF0ZShDb250cmFzdCA9ICJCbG9jayAxIC0gQmxvY2sgMiIpLAoKCmRyYXdzX2RpZmZfb3RoZXIgJT4lIAogIHN1bW1hcmlzZShgRGlmZiBpbiBvZmZzcHJpbmcgcHJvZHVjZWQgcGVyIDEwMGAgPSBtZWFuKGBCbG9jayAxIC0gQmxvY2sgM2ApKjEwMCwKICAgICAgICAgICAgYDIuNSVgID0gcXVhbnRpbGUoYEJsb2NrIDEgLSBCbG9jayAzYCwgcHJvYnMgPSAwLjAyNSkgKjEwMCwKICAgICAgICAgICAgYDk3LjUlYCA9IHF1YW50aWxlKGBCbG9jayAxIC0gQmxvY2sgM2AsIHByb2JzID0gMC45NzUpICoxMDApICU+JSAKICBtdXRhdGUoQ29udHJhc3QgPSAiQmxvY2sgMSAtIEJsb2NrIDMiKSwKCgpkcmF3c19kaWZmX290aGVyICU+JSAKICBzdW1tYXJpc2UoYERpZmYgaW4gb2Zmc3ByaW5nIHByb2R1Y2VkIHBlciAxMDBgID0gbWVhbihgM3hQIC0gVUJJYCkqMTAwLAogICAgICAgICAgICBgMi41JWAgPSBxdWFudGlsZShgM3hQIC0gVUJJYCwgcHJvYnMgPSAwLjAyNSkgKjEwMCwKICAgICAgICAgICAgYDk3LjUlYCA9IHF1YW50aWxlKGAzeFAgLSBVQklgLCBwcm9icyA9IDAuOTc1KSAqMTAwKSAlPiUgCiAgbXV0YXRlKENvbnRyYXN0ID0gIjN4UCAtIFVCSSIpCikgJT4lIAogIHNlbGVjdChDb250cmFzdCwgYERpZmYgaW4gb2Zmc3ByaW5nIHByb2R1Y2VkIHBlciAxMDBgLCBgMi41JWAsIGA5Ny41JWApICU+JSAKICBwYW5kZXIoc3BsaXQuY2VsbCA9IDQwLCBzcGxpdC50YWJsZSA9IEluZiwgcm91bmQgPSAyKQpgYGAKCiR+JAoKIyMgTWFsZSBmaXRuZXNzCgokfiQKClRvIGVzdGltYXRlIHRoZSBmaXRuZXNzIG9mIG1hbGVzIGNhcnJ5aW5nIGVhY2ggb2YgdGhlIHRocmVlIGNocm9tb3NvbWUgdHlwZXMsIHdlIGNvbmR1Y3RlZCBhbiBleHBlcmltZW50IHZlcnkgc2ltaWxhciB0byB0aGUgZmVtYWxlIGZpdG5lc3MgYXNzYXkuIEhvd2V2ZXIsIGJlY2F1c2UgbWFsZSBmaXRuZXNzIGhhcyBzdHJvbmdlciBjb3ZhcmlhbmNlIHdpdGggZmVydGlsaXNhdGlvbiBldmVudHMgdGhhbiBkb2VzIGZlbWFsZSBmaXRuZXNzLCB3ZSBjb25kdWN0ZWQgdGhlIG1hbGUgZml0bmVzcyBhc3NheSB3aXRoIGEgMToyIHNleCByYXRpbyAoZmVtYWxlOm1hbGUpIHJhdGhlciB0aGFuIHRoZSAxOjEgcmF0aW8gdXNlZCBpbiB0aGUgZmVtYWxlIGFzc2F5LiBUaGlzIGluY3JlYXNlcyB0aGUgc3RyZW5ndGggb2Ygc2V4dWFsIHNlbGVjdGlvbiBhbmQgaXMgYSBtb3JlIGFwcHJvcHJpYXRlIHdheSB0byBleHBvc2UgZGlmZmVyZW5jZXMgaW4gZml0bmVzcyBiZXR3ZWVuIGdyb3VwcyBvZiBtYWxlcy4gQXMgd2l0aCB0aGUgZmVtYWxlcywgd2UgY2FsY3VsYXRlZCBmaXRuZXNzIGFzIHRoZSBwcm9wb3J0aW9uIG9mIHJlZC1leWVkIG9mZnNwcmluZyBpbiB0aGUgdmlhbC4gCgpgYGB7cn0KCm1hbGVfZml0bmVzc19tb2RlbCA8LQogIGJybShUb3RhbF9yZWRfb2Zmc3ByaW5nIHwgdmludChUb3RhbF9vZmZzcHJpbmcpIH4gMSArIEluaGVyaXRhbmNlX3RyZWF0bWVudCArIEJsb2NrICsgR0ZQICsgKDF8UG9wdWxhdGlvbikgKyAoMXxSZWFyaW5nX3ZpYWwpLAogICAgICBkYXRhID0gbWFsZV9maXRuZXNzLCBmYW1pbHkgPSBiZXRhX2Jpbm9taWFsMiwgCiAgICAgIHByaW9yID0gYyhwcmlvcihub3JtYWwoMCwgMSksIGNsYXNzID0gSW50ZXJjZXB0KSwKICAgICAgICAgICAgICAgIHByaW9yKG5vcm1hbCgwLCAxLjUpLCBjbGFzcyA9IGIpLAogICAgICAgICAgICAgICAgcHJpb3IoZXhwb25lbnRpYWwoMSksIGNsYXNzID0gcGhpKSksCiAgICAgIGl0ZXIgPSA4MDAwLCB3YXJtdXAgPSA0MDAwLCBjaGFpbnMgPSA0LCBjb3JlcyA9IDQsCiAgICAgIGNvbnRyb2wgPSBsaXN0KGFkYXB0X2RlbHRhID0gMC45NSwgbWF4X3RyZWVkZXB0aCA9IDEwKSwKICAgICAgc2VlZCA9IDIsIHN0YW52YXJzID0gc3RhbnZhcnMsIGZpbGUgPSAiRml0cy9tYWxlX2ZpdG5lc3MubW9kZWwiKQoKCmZpeGVmKG1hbGVfZml0bmVzc19tb2RlbCkgJT4lIAogIGthYmxlKGRpZ2l0cyA9IDMpICU+JSAKICBrYWJsZV9zdHlsaW5nKCkKYGBgCgpgYGB7ciwgaW5jbHVkZT1GQUxTRX0KZXhwb3NlX2Z1bmN0aW9ucyhtYWxlX2ZpdG5lc3NfbW9kZWwsIHZlY3Rvcml6ZSA9IFRSVUUpCmBgYAoKUnVuIExPTyB0byBzZWUgaWYgd2UndmUgZWZmZWN0aXZlbHkgbW9kZWxsZWQgb3ZlciBkaXNwZXJzaW9uLgoKYGBge3J9CgptYWxlX2ZpdG5lc3NfbW9kZWwgPC0gYWRkX2NyaXRlcmlvbihtYWxlX2ZpdG5lc3NfbW9kZWwsIGNyaXRlcmlvbiA9ICJsb28iLCBmaWxlID0gIkZpdHMvbWFsZV9maXRuZXNzLm1vZGVsIikKCmxvbyhtYWxlX2ZpdG5lc3NfbW9kZWwpCgpgYGAKClRoZXJlIGlzIG9uZSBwb2ludCBoYXZpbmcgYSBsYXJnZSBlZmZlY3Qgb24gdGhlIHBvc3Rlcmlvci4gVXBvbiBpbnNwZWN0aW9uLCB0aGlzIGRhdGEgcG9pbnQgaXMgbm90IGFuIHVucmVhc29uYWJsZSBvbmUgYW5kIHRoZXJlIGlzIG5vIGNhdXNlIHRvIHJlbW92ZSBpdCBmcm9tIHRoZSBkYXRhc2V0LiBJdCBhbHNvIGRvZXMgbm90IGNoYW5nZSB0aGUgY2F1c2FsIGVmZmVjdCBvZiBpbmhlcml0YW5jZSB0cmVhdG1lbnQgb24gbWFsZSBmaXRuZXNzLgoKQ29uZHVjdCB0aGUgcG9zdGVyaW9yIHByZWRpY3RpdmUgY2hlY2suLi4KCmBgYHtyfQpwcF9jaGVjayhtYWxlX2ZpdG5lc3NfbW9kZWwsIHR5cGUgPSAiaGlzdCIsIG5kcmF3cyA9IDExLCBiaW53aWR0aCA9IDEwKSArCiAgdGhlbWVfbWluaW1hbCgpICsKICB0aGVtZShwYW5lbC5iYWNrZ3JvdW5kID0gZWxlbWVudF9ibGFuaygpKQpgYGAKCiMjIyBEZXJpdmUgZXN0aW1hdGVzIGZyb20gcG9zdGVyaW9yCgpHZXQgcHJlZGljdGlvbnMgZnJvbSB0aGUgbW9kZWwKCioqVGFibGUgUzUqKi4gRXN0aW1hdGVkIG1hbGUgZml0bmVzcyBmb3IgZmxpZXMgY2FycnlpbmcgYXV0b3NvbWVzIGRlcml2ZWQgZnJvbSBlYWNoIG9mIHRoZSB0aHJlZSBpbmhlcml0YW5jZSByZWdpbWVzLgoKYGBge3J9CgpkcmF3c19tIDwtIGFzX2RyYXdzX2RmKG1hbGVfZml0bmVzc19tb2RlbCkKCiMgcHJlZGljdGlvbnMgYXZlcmFnZWQgb3ZlciBtZWRpYXRvciB2YXJpYWJsZXMKCmRyYXdzX21hbGUgPC0KICBkcmF3c19tICAlPiUgCiAgbXV0YXRlKGBGZW1hbGUtbGltaXRlZGAgPSBpbnZfbG9naXRfc2NhbGVkKGJfSW50ZXJjZXB0ICsgYl9Jbmhlcml0YW5jZV90cmVhdG1lbnRGZW1hbGVfbGltaXRlZCksCiAgICAgICAgIGBNYWxlLWxpbWl0ZWRgID0gaW52X2xvZ2l0X3NjYWxlZChiX0ludGVyY2VwdCArIGJfSW5oZXJpdGFuY2VfdHJlYXRtZW50TWFsZV9saW1pdGVkKSwKICAgICAgICAgQ29udHJvbCA9IGludl9sb2dpdF9zY2FsZWQoYl9JbnRlcmNlcHQpKSAlPiUgCiAgc2VsZWN0KENvbnRyb2wsIGBGZW1hbGUtbGltaXRlZGAsIGBNYWxlLWxpbWl0ZWRgKSAlPiUgCiAgICBwaXZvdF9sb25nZXIoY29scyA9IGMoQ29udHJvbCwgYEZlbWFsZS1saW1pdGVkYCwgYE1hbGUtbGltaXRlZGApLAogICAgICAgICAgICAgICAgIG5hbWVzX3RvID0gIkluaGVyaXRhbmNlIHRyZWF0bWVudCIpICU+JSAKICByZW5hbWUocHJvcF9mb2NhbF9vZmZzcHJpbmcgPSB2YWx1ZSkKCgpkcmF3c19tYWxlICU+JSAKICBncm91cF9ieShgSW5oZXJpdGFuY2UgdHJlYXRtZW50YCkgJT4lIAogIHN1bW1hcmlzZShgRXN0aW1hdGVkIHByb3AuIG9mIG9mZnNwcmluZyBzaXJlZGAgPSBtZWFuKHByb3BfZm9jYWxfb2Zmc3ByaW5nKSwKICAgICAgICAgICAgYDIuNSVgID0gcXVhbnRpbGUocHJvcF9mb2NhbF9vZmZzcHJpbmcsIHByb2JzID0gMC4wMjUpLAogICAgICAgICAgICBgOTcuNSVgID0gcXVhbnRpbGUocHJvcF9mb2NhbF9vZmZzcHJpbmcsIHByb2JzID0gMC45NzUpKSAlPiUgCiAgcGFuZGVyKHNwbGl0LmNlbGwgPSA0MCwgc3BsaXQudGFibGUgPSBJbmYsIHJvdW5kID0gMykKCmBgYAoKKipUYWJsZSBTNioqLiBEaWZmZXJlbmNlcyBpbiBtYWxlIGZpdG5lc3MgYmV0d2VlbiBlYWNoIG9mIHRoZSB0aHJlZSBpbmhlcml0YW5jZSByZWdpbWVzLgoKYGBge3J9CmRyYXdzX2RpZmZfbSA8LSBkcmF3c19tICU+JSAKICBtdXRhdGUoYEZlbWFsZS1saW1pdGVkYCA9IGludl9sb2dpdF9zY2FsZWQoYl9JbnRlcmNlcHQgKyBiX0luaGVyaXRhbmNlX3RyZWF0bWVudEZlbWFsZV9saW1pdGVkKSwKICAgICAgICAgYE1hbGUtbGltaXRlZGAgPSBpbnZfbG9naXRfc2NhbGVkKGJfSW50ZXJjZXB0ICsgYl9Jbmhlcml0YW5jZV90cmVhdG1lbnRNYWxlX2xpbWl0ZWQpLAogICAgICAgICBDb250cm9sID0gaW52X2xvZ2l0X3NjYWxlZChiX0ludGVyY2VwdCkpICU+JQogIG11dGF0ZShgRmVtYWxlIC0gQ29udHJvbGAgPSBgRmVtYWxlLWxpbWl0ZWRgIC0gQ29udHJvbCwKICAgICAgICAgYE1hbGUgLSBDb250cm9sYCA9IGBNYWxlLWxpbWl0ZWRgIC0gQ29udHJvbCwKICAgICAgICAgYEZlbWFsZSAtIE1hbGVgID0gYEZlbWFsZS1saW1pdGVkYCAtIGBNYWxlLWxpbWl0ZWRgKSAlPiUgCiAgc2VsZWN0KGBGZW1hbGUgLSBDb250cm9sYCwgYE1hbGUgLSBDb250cm9sYCwgYEZlbWFsZSAtIE1hbGVgKQoKIyBGaW5kIGRpZmZlcmVuY2VzIGFuZCB2aXN1YWxpc2UgaW4gdGFibGUKCnJiaW5kKAogIGRyYXdzX2RpZmZfbSAlPiUgCiAgICBzdW1tYXJpc2UoYERpZmYgaW4gb2Zmc3ByaW5nIHByb2R1Y2VkIHBlciAxMDBgID0gbWVhbihgRmVtYWxlIC0gQ29udHJvbGApKjEwMCwKICAgICAgICAgICAgICBgMi41JWAgPSBxdWFudGlsZShgRmVtYWxlIC0gQ29udHJvbGAsIHByb2JzID0gMC4wMjUpICoxMDAsCiAgICAgICAgICAgICAgYDk3LjUlYCA9IHF1YW50aWxlKGBGZW1hbGUgLSBDb250cm9sYCwgcHJvYnMgPSAwLjk3NSkgKjEwMCkgJT4lIAogICAgbXV0YXRlKENvbnRyYXN0ID0gIkZlbWFsZSBpbmhlcml0ZWQgLSBDb250cm9sIiksCiAgCiAgZHJhd3NfZGlmZl9tICU+JSAKICAgIHN1bW1hcmlzZShgRGlmZiBpbiBvZmZzcHJpbmcgcHJvZHVjZWQgcGVyIDEwMGAgPSBtZWFuKGBNYWxlIC0gQ29udHJvbGApKjEwMCwKICAgICAgICAgICAgICBgMi41JWAgPSBxdWFudGlsZShgTWFsZSAtIENvbnRyb2xgLCBwcm9icyA9IDAuMDI1KSAqMTAwLAogICAgICAgICAgICAgIGA5Ny41JWAgPSBxdWFudGlsZShgTWFsZSAtIENvbnRyb2xgLCBwcm9icyA9IDAuOTc1KSAqMTAwKSAlPiUgCiAgICBtdXRhdGUoQ29udHJhc3QgPSAiTWFsZSBpbmhlcml0ZWQgLSBDb250cm9sIiksCiAgCiAgCiAgZHJhd3NfZGlmZl9tICU+JSAKICAgIHN1bW1hcmlzZShgRGlmZiBpbiBvZmZzcHJpbmcgcHJvZHVjZWQgcGVyIDEwMGAgPSBtZWFuKGBGZW1hbGUgLSBNYWxlYCkqMTAwLAogICAgICAgICAgICAgIGAyLjUlYCA9IHF1YW50aWxlKGBGZW1hbGUgLSBNYWxlYCwgcHJvYnMgPSAwLjAyNSkgKjEwMCwKICAgICAgICAgICAgICBgOTcuNSVgID0gcXVhbnRpbGUoYEZlbWFsZSAtIE1hbGVgLCBwcm9icyA9IDAuOTc1KSAqMTAwKSAlPiUgCiAgICBtdXRhdGUoQ29udHJhc3QgPSAiRmVtYWxlIGluaGVyaXRlZCAtIE1hbGUgaW5oZXJpdGVkIikKKSAlPiUgCiAgc2VsZWN0KENvbnRyYXN0LCBgRGlmZiBpbiBvZmZzcHJpbmcgcHJvZHVjZWQgcGVyIDEwMGAsIGAyLjUlYCwgYDk3LjUlYCkgJT4lIAogIHBhbmRlcihzcGxpdC5jZWxsID0gNDAsIHNwbGl0LnRhYmxlID0gSW5mLCByb3VuZCA9IDIpCgpgYGAKCioqVGhlIGVmZmVjdHMgb2YgdGhlIGJsb2NrIGFuZCBHRlAgcHJlZGljdG9ycyoqCgoqKlRhYmxlIFM3KiouIFRoZSBlZmZlY3RzIG9mIHRoZSBmaXhlZCBwcmVkaWN0b3IgdmFyaWFibGVzIG9uIG1hbGUgZml0bmVzcyB0aGF0IGFyZSBub3QgZGlyZWN0bHkgcmVsYXRlZCB0byBpbnRyYWxvY3VzIHNleHVhbCBjb25mbGljdC4gTWFsZSBmaXRuZXNzIG1lYXN1cmVkIGluIEJsb2NrIDIgd2FzIGhpZ2hlciB0aGFuIHRoYXQgbWVhc3VyZWQgaW4gQmxvY2tzIDEgYW5kIDMuIFRoZXJlIHdhcyBubyBlZmZlY3Qgb2YgR0ZQIHRyYW5zZ2VuZSBvbiBtYWxlIGZpdG5lc3MuCgpgYGB7cn0KICAKZHJhd3NfZGlmZl9vdGhlcl9tIDwtIGRyYXdzX20gICU+JSAKICBzZWxlY3QoYl9JbnRlcmNlcHQsIGJfQmxvY2syLCBiX0Jsb2NrMywgYl9HRlBVQkkpICU+JSAKICBtdXRhdGUoYEJsb2NrIDEsIDN4UGAgPSBpbnZfbG9naXRfc2NhbGVkKGJfSW50ZXJjZXB0KSwKICAgICAgICAgYEJsb2NrIDJgID0gaW52X2xvZ2l0X3NjYWxlZChiX0ludGVyY2VwdCArIGJfQmxvY2syKSwKICAgICAgICAgYEJsb2NrIDNgID0gaW52X2xvZ2l0X3NjYWxlZChiX0ludGVyY2VwdCArIGJfQmxvY2szKSwKICAgICAgICAgVUJJID0gaW52X2xvZ2l0X3NjYWxlZChiX0ludGVyY2VwdCArIGJfR0ZQVUJJKSkgJT4lCiAgbXV0YXRlKGBCbG9jayAxIC0gQmxvY2sgMmAgPSBgQmxvY2sgMSwgM3hQYCAtIGBCbG9jayAyYCwKICAgICAgICAgYEJsb2NrIDEgLSBCbG9jayAzYCA9IGBCbG9jayAxLCAzeFBgIC0gYEJsb2NrIDNgLAogICAgICAgICBgM3hQIC0gVUJJYCA9IGBCbG9jayAxLCAzeFBgIC0gVUJJKSAlPiUgCiAgc2VsZWN0KGBCbG9jayAxIC0gQmxvY2sgMmAsIGBCbG9jayAxIC0gQmxvY2sgM2AsIGAzeFAgLSBVQklgKQoKIyBGaW5kIGRpZmZlcmVuY2VzIGFuZCB2aXN1YWxpc2UgaW4gdGFibGUKCnJiaW5kKApkcmF3c19kaWZmX290aGVyX20gJT4lIAogIHN1bW1hcmlzZShgRGlmZiBpbiBvZmZzcHJpbmcgcHJvZHVjZWQgcGVyIDEwMGAgPSBtZWFuKGBCbG9jayAxIC0gQmxvY2sgMmApKjEwMCwKICAgICAgICAgICAgYDIuNSVgID0gcXVhbnRpbGUoYEJsb2NrIDEgLSBCbG9jayAyYCwgcHJvYnMgPSAwLjAyNSkgKjEwMCwKICAgICAgICAgICAgYDk3LjUlYCA9IHF1YW50aWxlKGBCbG9jayAxIC0gQmxvY2sgMmAsIHByb2JzID0gMC45NzUpICoxMDApICU+JSAKICBtdXRhdGUoQ29udHJhc3QgPSAiQmxvY2sgMSAtIEJsb2NrIDIiKSwKCgpkcmF3c19kaWZmX290aGVyX20gJT4lIAogIHN1bW1hcmlzZShgRGlmZiBpbiBvZmZzcHJpbmcgcHJvZHVjZWQgcGVyIDEwMGAgPSBtZWFuKGBCbG9jayAxIC0gQmxvY2sgM2ApKjEwMCwKICAgICAgICAgICAgYDIuNSVgID0gcXVhbnRpbGUoYEJsb2NrIDEgLSBCbG9jayAzYCwgcHJvYnMgPSAwLjAyNSkgKjEwMCwKICAgICAgICAgICAgYDk3LjUlYCA9IHF1YW50aWxlKGBCbG9jayAxIC0gQmxvY2sgM2AsIHByb2JzID0gMC45NzUpICoxMDApICU+JSAKICBtdXRhdGUoQ29udHJhc3QgPSAiQmxvY2sgMSAtIEJsb2NrIDMiKSwKCgpkcmF3c19kaWZmX290aGVyX20gJT4lIAogIHN1bW1hcmlzZShgRGlmZiBpbiBvZmZzcHJpbmcgcHJvZHVjZWQgcGVyIDEwMGAgPSBtZWFuKGAzeFAgLSBVQklgKSoxMDAsCiAgICAgICAgICAgIGAyLjUlYCA9IHF1YW50aWxlKGAzeFAgLSBVQklgLCBwcm9icyA9IDAuMDI1KSAqMTAwLAogICAgICAgICAgICBgOTcuNSVgID0gcXVhbnRpbGUoYDN4UCAtIFVCSWAsIHByb2JzID0gMC45NzUpICoxMDApICU+JSAKICBtdXRhdGUoQ29udHJhc3QgPSAiM3hQIC0gVUJJIikKKSAlPiUgCiAgc2VsZWN0KENvbnRyYXN0LCBgRGlmZiBpbiBvZmZzcHJpbmcgcHJvZHVjZWQgcGVyIDEwMGAsIGAyLjUlYCwgYDk3LjUlYCkgJT4lIAogIHBhbmRlcihzcGxpdC5jZWxsID0gNDAsIHNwbGl0LnRhYmxlID0gSW5mLCByb3VuZCA9IDIpCgpgYGAKCiR+JAoKIyBCdWlsZGluZyBGaWd1cmUgMgoKYGBge3IsIGZpZy5oZWlnaHQ9OCwgZmlnLndpZHRoPTh9CgojIGZlbWFsZSBwbG90cwoKZl8xIDwtCiAgZHJhd3NfZmVtYWxlICU+JSAKICBtdXRhdGUoYEluaGVyaXRhbmNlIHRyZWF0bWVudGAgPSBmY3RfcmVsZXZlbChgSW5oZXJpdGFuY2UgdHJlYXRtZW50YCwgIkZlbWFsZS1saW1pdGVkIiwgIkNvbnRyb2wiLCAiTWFsZS1saW1pdGVkIikpICU+JSAKICBnZ3Bsb3QoYWVzKGBJbmhlcml0YW5jZSB0cmVhdG1lbnRgLCBwcm9wX2ZvY2FsX29mZnNwcmluZykpICsgCiAgc3RhdF9oYWxmZXllKGZpbGwgPSAiZ3JleSIsIC53aWR0aCA9IGMoMC42NiwgMC45NSksIGFscGhhID0gMSwKICAgICAgICAgICAgICAgcG9pbnRfaW50ZXJ2YWwgPSAibWVhbl9xaSIsIHBvaW50X2ZpbGwgPSAid2hpdGUiLAogICAgICAgICAgICAgICBzaGFwZSA9IDIxLCBwb2ludF9zaXplID0gMywgc3Ryb2tlID0gMS41KSArICMgd2lkdGggaW5kaWNhdGVzIHRoZSB1bmNlcnRhaW50eSBpbnRlcnZhbHM6IHdlIGhhdmUgNjYlIGFuZCA5NSUgaW50ZXJ2YWxzCiAgI3NjYWxlX2ZpbGxfbWFudWFsKHZhbHVlcyA9IG1ldC5icmV3ZXIoIkhpcm9zaGlnZSIsIDMpKSArCiAgY29vcmRfZmxpcCgpICsKICB5bGFiKCJGZW1hbGUgZml0bmVzc1xuKHByb3AuIG9mZnNwcmluZyBwcm9kdWNlZCkiKSArCiAgdGhlbWVfYncoKSArIAogIHRoZW1lKGxlZ2VuZC5wb3NpdGlvbiA9ICJub25lIiwKICAgICAgICBwYW5lbC5ncmlkLm1pbm9yID0gZWxlbWVudF9ibGFuaygpKQoKZl8yIDwtCiAgZHJhd3NfZGlmZiAlPiUgCiAgZ2F0aGVyKGtleSA9IHBhcmFtZXRlciwgdmFsdWUgPSBgRml0bmVzcyBkaWZmZXJlbmNlYCkgJT4lIAogIGFzX3RpYmJsZSgpICU+JSAgIAoKICBnZ3Bsb3QoYWVzKHBhcmFtZXRlciwgYEZpdG5lc3MgZGlmZmVyZW5jZWApKSArIAogIHN0YXRfaGFsZmV5ZSgud2lkdGggPSBjKDAuNjYsIDAuOTUpLCBhbHBoYSA9IDAuOSwgcG9pbnRfaW50ZXJ2YWwgPSAibWVhbl9xaSIsCiAgICAgICAgICAgICAgIHNsYWJfZmlsbCA9ICJncmV5IiwKICAgICAgICAgICAgICAgc2hhcGUgPSAyMSwgcG9pbnRfc2l6ZSA9IDMsIHN0cm9rZSA9IDEuNSwKICAgICAgICAgICAgICAgcG9pbnRfZmlsbCA9ICJ3aGl0ZSIpICsgIyB3aWR0aCBpbmRpY2F0ZXMgdGhlIHVuY2VydGFpbnR5IGludGVydmFsczogaGVyZSB3ZSBoYXZlIDY2JSBhbmQgOTUlIGludGVydmFscwogIGNvb3JkX2ZsaXAoKSArCiAgZ2VvbV9obGluZSh5aW50ZXJjZXB0ID0gMCwgbGluZXR5cGUgPSAyKSArCiAgI3NjYWxlX3lfY29udGludW91cyhicmVha3MgPSBjKCwgMCwgMSkpICsKICB4bGFiKCJUcmVhdG1lbnQgY29udHJhc3QiKSArCiAgeWxhYigiRmVtYWxlIGZpdG5lc3MgZGlmZmVyZW5jZVxuKHByb3AuIG9mZnNwcmluZyBwcm9kdWNlZCkiKSArCiAgdGhlbWVfYncoKSArIAogIHRoZW1lKGxlZ2VuZC5wb3NpdGlvbiA9ICJub25lIiwKICAgICAgICBwYW5lbC5ncmlkLm1pbm9yID0gZWxlbWVudF9ibGFuaygpKQoKIyBtYWxlIHBsb3RzCgpmXzMgPC0KICBkcmF3c19tYWxlICU+JSAKICBtdXRhdGUoYEluaGVyaXRhbmNlIHRyZWF0bWVudGAgPSBmY3RfcmVsZXZlbChgSW5oZXJpdGFuY2UgdHJlYXRtZW50YCwgIkZlbWFsZS1saW1pdGVkIiwgIkNvbnRyb2wiLCAiTWFsZS1saW1pdGVkIikpICU+JSAKICBnZ3Bsb3QoYWVzKGBJbmhlcml0YW5jZSB0cmVhdG1lbnRgLCBwcm9wX2ZvY2FsX29mZnNwcmluZykpICsgCiAgIHN0YXRfaGFsZmV5ZShmaWxsID0gImdyZXkiLCAud2lkdGggPSBjKDAuNjYsIDAuOTUpLCBhbHBoYSA9IDEsCiAgICAgICAgICAgICAgIHBvaW50X2ludGVydmFsID0gIm1lYW5fcWkiLCBwb2ludF9maWxsID0gIndoaXRlIiwKICAgICAgICAgICAgICAgc2hhcGUgPSAyMSwgcG9pbnRfc2l6ZSA9IDMsIHN0cm9rZSA9IDEuNSkgKyAjIHdpZHRoIGluZGljYXRlcyB0aGUgdW5jZXJ0YWludHkgaW50ZXJ2YWxzOiBoZXJlIHdlIGhhdmUgNjYlIGFuZCA5NSUgaW50ZXJ2YWxzCiAgc2NhbGVfZmlsbF9tYW51YWwodmFsdWVzID0gbWV0LmJyZXdlcigiSGlyb3NoaWdlIiwgMykpICsKICBjb29yZF9mbGlwKCkgKwogIHlsYWIoIk1hbGUgZml0bmVzc1xuKHByb3AuIG9mZnNwcmluZyBwcm9kdWNlZCkiKSArCiAgdGhlbWVfYncoKSArIAogIHRoZW1lKGxlZ2VuZC5wb3NpdGlvbiA9ICJub25lIiwKICAgICAgICBwYW5lbC5ncmlkLm1pbm9yID0gZWxlbWVudF9ibGFuaygpKQoKZl80IDwtCiAgZHJhd3NfZGlmZl9tICU+JQogIGdhdGhlcihrZXkgPSBwYXJhbWV0ZXIsIHZhbHVlID0gYEZpdG5lc3MgZGlmZmVyZW5jZWApICU+JSAKICBhc190aWJibGUoKSAlPiUgCiAgZ2dwbG90KGFlcyhwYXJhbWV0ZXIsIGBGaXRuZXNzIGRpZmZlcmVuY2VgKSkgKyAKICBzdGF0X2hhbGZleWUoLndpZHRoID0gYygwLjY2LCAwLjk1KSwgYWxwaGEgPSAwLjksIHBvaW50X2ludGVydmFsID0gIm1lYW5fcWkiLAogICAgICAgICAgICAgICBzbGFiX2ZpbGwgPSAiZ3JleSIsCiAgICAgICAgICAgICAgIHNoYXBlID0gMjEsIHBvaW50X3NpemUgPSAzLCBzdHJva2UgPSAxLjUsCiAgICAgICAgICAgICAgIHBvaW50X2ZpbGwgPSAid2hpdGUiKSArICMgd2lkdGggaW5kaWNhdGVzIHRoZSB1bmNlcnRhaW50eSBpbnRlcnZhbHM6IGhlcmUgd2UgaGF2ZSA2NiUgYW5kIDk1JSBpbnRlcnZhbHMKICBzY2FsZV9maWxsX21hbnVhbCh2YWx1ZXMgPSBtZXQuYnJld2VyKCJIb2t1c2FpMyIsIDMpKSArCiAgY29vcmRfZmxpcCgpICsKICBnZW9tX2hsaW5lKHlpbnRlcmNlcHQgPSAwLCBsaW5ldHlwZSA9IDIpICsKICBzY2FsZV95X2NvbnRpbnVvdXMoYnJlYWtzID0gYygtMC4yLCAtMC4xLCAwLCAwLjEsIDAuMikpICsKICB4bGFiKCJUcmVhdG1lbnQgY29udHJhc3QiKSArCiAgeWxhYigiTWFsZSBmaXRuZXNzIGRpZmZlcmVuY2Vcbihwcm9wLiBvZmZzcHJpbmcgc2lyZWQpIikgKwogIHRoZW1lX2J3KCkgKyAKICB0aGVtZShsZWdlbmQucG9zaXRpb24gPSAibm9uZSIsCiAgICAgICAgcGFuZWwuZ3JpZC5taW5vciA9IGVsZW1lbnRfYmxhbmsoKSkKCgooZl8xICsgZl8yKSAvKGZfMyArIGZfNCkgKyAKICBwbG90X2Fubm90YXRpb24odGFnX2xldmVscyA9ICdhJykKCmBgYAoKKipGaWd1cmUgMioqOiAqKmEqKiBzaG93cyB0aGUgZXN0aW1hdGVkIGRpc3RyaWJ1dGlvbiBvZiB0aGUgbWVhbiBmb3IgZmVtYWxlIGZpdG5lc3MgZm9yIGZsaWVzIGNhcnJ5aW5nIGF1dG9zb21lcyB0aGF0IGhhZCBwcmV2aW91c2x5IGV4cGVyaWVuY2VkIHVuY29uc3RyYWluZWQgaW5oZXJpdGFuY2UgKGNvbnRyb2wpLCBmZW1hbGUtbGltaXRlZCBpbmhlcml0YW5jZSBvciBtYWxlLWxpbWl0ZWQgaW5oZXJpdGFuY2UuICoqYioqIHNob3dzIHRoZSBkaWZmZXJlbmNlIGNvbnRyYXN0IGluIGZlbWFsZSBmaXRuZXNzIGJldHdlZW4gZWFjaCBvZiB0aGUgdGhyZWUgaW5oZXJpdGFuY2UgdHJlYXRtZW50cy4gVGhpcyBkaWZmZXJlbmNlIGlzIG9uIHRoZSBwcm9wb3J0aW9uIHNjYWxlLCB3aGVyZSBhIHZhbHVlIG9mIDAuMSBpbmRpY2F0ZXMgdGhhdCBmZW1hbGVzIG9mIGEgZ2l2ZW4gaW5oZXJpdGFuY2UgdHJlYXRtZW50IHByb2R1Y2UgMTAgbW9yZSBvZmZzcHJpbmcgcGVyIGV2ZXJ5IDEwMCB3aGVuIGNvaGFiaXRpbmcgd2l0aCBfYndfIGNvbXBldGl0b3IgZmVtYWxlcy4gKipjKiogYW5kICoqZCoqIGRlcGljdCB0aGUgc2FtZSB0aGluZ3MgYXMgKiphKiogYW5kICoqYioqLCBleGNlcHQgZm9yIG1hbGUgZml0bmVzcy4KCg==